<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss version="2.0"><channel><title>Keegan Carruthers-Smith's Blog</title><link>http://people.cs.uct.ac.za/~ksmith</link><description>Blog on what interests me, which is mostly algorithms and data-structures.</description><copyright>2011</copyright><lastBuildDate>Fri, 26 Oct 2012 10:00:00 -0000</lastBuildDate><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/keegancsmith_blog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="keegancsmith_blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Suspend on Lid Close in Ubuntu</title><link>http://people.cs.uct.ac.za/~ksmith/2012/suspend-on-lid-close-in-ubuntu.html</link><description>&lt;div class=section id=suspend-on-lid-close-in-ubuntu&gt;
&lt;h1&gt;Suspend on Lid Close in Ubuntu&lt;/h1&gt;
&lt;p&gt;I just got a new laptop (Lenovo T420s) and installed Ubuntu 12.10. The default
behaviour when closing the lid is to show a black screen and nothing else. I
don’t know who prefers this use case (maybe external monitor users?) My issue
might also be that I don’t use gnome-power-manager which may override the
default behaviour. What I would prefer is suspending and showing a lock screen
when the lid is opened up again.&lt;/p&gt;
&lt;p&gt;So how do we go about fixing this? Well closing the lid sends an ACPI event,
and on Ubuntu there are a bunch of shell scripts in &lt;cite&gt;/etc/acpi&lt;/cite&gt; which get
called depending on the event. In the case of a lid close it runs
&lt;cite&gt;/etc/acpi/lid.sh&lt;/cite&gt;. Reading that file we can see that it runs a file
&lt;cite&gt;/etc/acpi/local/lid.post.sh&lt;/cite&gt; if it exists and is executable.&lt;/p&gt;
&lt;p&gt;If we save &lt;cite&gt;/etc/acpi/local/lid.post.sh&lt;/cite&gt; as&lt;/p&gt;
&lt;div class=highlight-bash&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=c&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=c&gt;# On lid close show lock screen and suspend laptop.&lt;/span&gt;

. /usr/share/acpi-support/power-funcs

grep -q closed /proc/acpi/button/lid/*/state
&lt;span class=k&gt;if&lt;/span&gt; &lt;span class=o&gt;[&lt;/span&gt; &lt;span class=nv&gt;$?&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; 0 &lt;span class=o&gt;]&lt;/span&gt;; &lt;span class=k&gt;then&lt;/span&gt;
&lt;span class=k&gt;    for &lt;/span&gt;x in /tmp/.X11-unix/*; &lt;span class=k&gt;do&lt;/span&gt;
&lt;span class=k&gt;        &lt;/span&gt;&lt;span class=nv&gt;displaynum&lt;/span&gt;&lt;span class=o&gt;=&lt;/span&gt;&lt;span class=sb&gt;`&lt;/span&gt;&lt;span class=nb&gt;echo&lt;/span&gt; &lt;span class=nv&gt;$x&lt;/span&gt; | sed s#/tmp/.X11-unix/X##&lt;span class=sb&gt;`&lt;/span&gt;
        getXuser;
        &lt;span class=k&gt;if&lt;/span&gt; &lt;span class=o&gt;[&lt;/span&gt; x&lt;span class=s2&gt;"$XAUTHORITY"&lt;/span&gt; !&lt;span class=o&gt;=&lt;/span&gt; x&lt;span class=s2&gt;""&lt;/span&gt; &lt;span class=o&gt;]&lt;/span&gt;; &lt;span class=k&gt;then&lt;/span&gt;
&lt;span class=k&gt;            &lt;/span&gt;&lt;span class=nb&gt;export &lt;/span&gt;&lt;span class=nv&gt;DISPLAY&lt;/span&gt;&lt;span class=o&gt;=&lt;/span&gt;&lt;span class=s2&gt;":$displaynum"&lt;/span&gt;
            su &lt;span class=nv&gt;$user&lt;/span&gt; -c &lt;span class=s1&gt;'gnome-screensaver-command --lock'&lt;/span&gt;
        &lt;span class=k&gt;fi&lt;/span&gt;
&lt;span class=k&gt;    done&lt;/span&gt;
&lt;span class=k&gt;    &lt;/span&gt;pm-suspend
&lt;span class=k&gt;fi&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;then on suspend we run &lt;cite&gt;pm-suspend&lt;/cite&gt; as root and &lt;cite&gt;gnome-screensaver-command
–lock&lt;/cite&gt; for every user which has an X session running. Remember to make the
file executable:&lt;/p&gt;
&lt;div class=highlight-python&gt;&lt;pre&gt;$ sudo chown root:root /etc/acpi/local/lid.post.sh
$ sudo chmod 0755 /etc/acpi/local/lid.post.sh&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can pretty much do anything on lid close (and other acpi events) if you
know a bit of scripting. An example of something would be checking if any
external monitors are connected, and if they are don’t suspend and switch off
the laptop screen (just a bit of xrandr magic).&lt;/p&gt;
&lt;/div&gt;
</description><pubDate>Fri, 26 Oct 2012 10:00:00 -0000</pubDate><guid>http://people.cs.uct.ac.za/~ksmith/2012/suspend-on-lid-close-in-ubuntu.html</guid></item><item><title>DNS Caching with Network Manager</title><link>http://people.cs.uct.ac.za/~ksmith/2012/dns-caching-with-network-manager.html</link><description>&lt;div class=section id=dns-caching-with-network-manager&gt;
&lt;h1&gt;DNS Caching with Network Manager&lt;/h1&gt;
&lt;p&gt;I have been finding the DNS server on my router to be a bit flaky. It can take
up-to 2 seconds to resolve a domain name and does no caching. This leads to
slower network performance in applications that don’t do there own DNS
caching.&lt;/p&gt;
&lt;p&gt;There is an easy fix to this in Linux, just install &lt;a class="reference external" href=http://thekelleys.org.uk/dnsmasq/doc.html&gt;dnsmasq&lt;/a&gt;, enable its DNS
server and add &lt;cite&gt;127.0.0.1&lt;/cite&gt; to your &lt;cite&gt;/etc/resolv.conf&lt;/cite&gt;. dnsmasq then uses the
nameservers specified in &lt;cite&gt;/etc/resolv.conf&lt;/cite&gt; (other than itself) to lookup
hostnames.&lt;/p&gt;
&lt;p&gt;Unfortunately if you use Network Manager, it manages your &lt;cite&gt;/etc/resolv.conf&lt;/cite&gt;
and there doesn’t seem to be a way to add in custom entries on top of the ones
Network Manager receives from DHCP. However, each time Network Manager brings
up a network interface it runs the scripts in &lt;cite&gt;/etc/network/if-up.d/&lt;/cite&gt;. The
script below prepends the nameservers &lt;cite&gt;127.0.0.1&lt;/cite&gt; (dnsmasq’s DNS server) and
&lt;cite&gt;8.8.4.4&lt;/cite&gt; (Google’s open DNS server) to &lt;cite&gt;/etc/resolv.conf&lt;/cite&gt;.&lt;/p&gt;
&lt;div class=highlight-bash&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=c&gt;#!/bin/sh&lt;/span&gt;
&lt;span class=c&gt;# Add dnsmasq caching server and google dns to /etc/resolv.conf&lt;/span&gt;

&lt;span class=nb&gt;set&lt;/span&gt; -e

&lt;span class=c&gt;# No need to do anything on loopback.&lt;/span&gt;
&lt;span class=k&gt;if&lt;/span&gt; &lt;span class=o&gt;[&lt;/span&gt; &lt;span class=s2&gt;"$IFACE"&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; lo &lt;span class=o&gt;]&lt;/span&gt;; &lt;span class=k&gt;then &lt;/span&gt;&lt;span class=nb&gt;exit &lt;/span&gt;0; &lt;span class=k&gt;fi&lt;/span&gt;

&lt;span class=c&gt;# Only run from ifup.&lt;/span&gt;
&lt;span class=k&gt;if&lt;/span&gt; &lt;span class=o&gt;[&lt;/span&gt; &lt;span class=s2&gt;"$MODE"&lt;/span&gt; !&lt;span class=o&gt;=&lt;/span&gt; start &lt;span class=o&gt;]&lt;/span&gt;; &lt;span class=k&gt;then &lt;/span&gt;&lt;span class=nb&gt;exit &lt;/span&gt;0; &lt;span class=k&gt;fi&lt;/span&gt;

cp /etc/resolv.conf /etc/resolv.conf.tmp
&lt;span class=nb&gt;echo &lt;/span&gt;nameserver 127.0.0.1 &amp;gt; /etc/resolv.conf
&lt;span class=nb&gt;echo &lt;/span&gt;nameserver 8.8.4.4 &amp;gt;&amp;gt; /etc/resolv.conf
cat /etc/resolv.conf.tmp &amp;gt;&amp;gt; /etc/resolv.conf
rm /etc/resolv.conf.tmp
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here are some step by step instructions to get it working in Ubuntu/Debian:&lt;/p&gt;
&lt;div class=highlight-python&gt;&lt;pre&gt;$ sudo apt-get install dnsmasq
$ # Add `listen-address=127.0.0.1` to `/etc/dnsmasq.conf`
$ sudo /etc/init.d/dnsmasq restart
$ # Copy the above script into a file called dnsmasq-cache
$ chmod +x dnsmasq-cache
$ sudo mv dnsmasq-cache /etc/network/if-up.d/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now when Network Manager brings up an interface it should enable use of
dnsmasq’s caching DNS server. Take care when configuring dnsmasq to not enable
it’s DHCP server unless you intend on using it. This can cause havoc on some
LANs.&lt;/p&gt;
&lt;p&gt;Now DNS records which haven’t expired should be super quick after the first
access. On a simple test over crappy tethered internet I go from 952 msec to 0
msec for a query:&lt;/p&gt;
&lt;div class=highlight-python&gt;&lt;pre&gt;$ dig www.uct.ac.za | grep 'Query time'
;; Query time: 952 msec
$ dig www.uct.ac.za | grep 'Query time'
;; Query time: 0 msec&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><pubDate>Wed, 11 Jan 2012 15:00:00 -0000</pubDate><guid>http://people.cs.uct.ac.za/~ksmith/2012/dns-caching-with-network-manager.html</guid></item><item><title>Better Python Flymake Integration in Emacs</title><link>http://people.cs.uct.ac.za/~ksmith/2011/better-python-flymake-integration-in-emacs.html</link><description>&lt;div class=section id=better-python-flymake-integration-in-emacs&gt;
&lt;h1&gt;Better Python Flymake Integration in Emacs&lt;/h1&gt;
&lt;p&gt;Flymake is a great feature in Emacs for getting warnings and errors in source
code as you type it. When I am coding in Python I like to use &lt;a class="reference external" href=http://pypi.python.org/pypi/pep8&gt;PEP8&lt;/a&gt; and
&lt;a class="reference external" href=http://pypi.python.org/pypi/pyflakes&gt;pyflakes&lt;/a&gt; to warn me about stylistic and potential errors. I integrated those
tools into Emacs by following the guide at
&lt;a class="reference external" href=http://reinout.vanrees.org/weblog/2010/05/11/pep8-pyflakes-emacs.html&gt;http://reinout.vanrees.org/weblog/2010/05/11/pep8-pyflakes-emacs.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, I find it annoying that all output from PEP8 and pyflakes is treated
as an error by flymake. Notice in the following image that only the last
highlighted line is an error, while the rest of the lines should be treated as
warnings.&lt;/p&gt;
&lt;img alt=../_images/flymake-before.png src=http://people.cs.uct.ac.za/~ksmith/_images/flymake-before.png&gt;
&lt;p&gt;Wouldn’t it be much better if flymake treated the warning lines as warnings,
and highlighted them as such?&lt;/p&gt;
&lt;img alt=../_images/flymake-after.png src=http://people.cs.uct.ac.za/~ksmith/_images/flymake-after.png&gt;
&lt;p&gt;We can accomplish this by modifying the output of PEP8 and pyflakes such that
flymake correctly recognizes messages as warnings. The following code does
just that (and runs both PEP8 and pyflakes on the input):&lt;/p&gt;
&lt;div class=highlight-python&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=c&gt;#!/usr/bin/env python&lt;/span&gt;

&lt;span class=kn&gt;import&lt;/span&gt; &lt;span class=nn&gt;commands&lt;/span&gt;
&lt;span class=kn&gt;import&lt;/span&gt; &lt;span class=nn&gt;re&lt;/span&gt;
&lt;span class=kn&gt;import&lt;/span&gt; &lt;span class=nn&gt;sys&lt;/span&gt;

&lt;span class=k&gt;def&lt;/span&gt; &lt;span class=nf&gt;make_re&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=o&gt;*&lt;/span&gt;&lt;span class=n&gt;msgs&lt;/span&gt;&lt;span class=p&gt;):&lt;/span&gt;
    &lt;span class=k&gt;return&lt;/span&gt; &lt;span class=n&gt;re&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;compile&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=s&gt;'(&lt;/span&gt;&lt;span class=si&gt;%s&lt;/span&gt;&lt;span class=s&gt;)'&lt;/span&gt; &lt;span class=o&gt;%&lt;/span&gt; &lt;span class=s&gt;'|'&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;join&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;msgs&lt;/span&gt;&lt;span class=p&gt;))&lt;/span&gt;

&lt;span class=n&gt;pyflakes_ignore&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=n&gt;make_re&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=s&gt;'unable to detect undefined names'&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
&lt;span class=n&gt;pyflakes_warning&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=n&gt;make_re&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;
    &lt;span class=s&gt;'imported but unused'&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt;
    &lt;span class=s&gt;'is assigned to but never used'&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt;
    &lt;span class=s&gt;'redefinition of unused'&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt;
&lt;span class=p&gt;)&lt;/span&gt;
&lt;span class=n&gt;pep8_ignore&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=p&gt;[&lt;/span&gt;&lt;span class=s&gt;'E501'&lt;/span&gt;&lt;span class=p&gt;]&lt;/span&gt;
&lt;span class=n&gt;pep8_warning&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=n&gt;make_re&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=s&gt;'.'&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;

&lt;span class=k&gt;def&lt;/span&gt; &lt;span class=nf&gt;run&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;cmd&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=n&gt;ignore_re&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=n&gt;warning_re&lt;/span&gt;&lt;span class=p&gt;):&lt;/span&gt;
    &lt;span class=n&gt;output&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=n&gt;commands&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;getoutput&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;cmd&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
    &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=n&gt;line&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=n&gt;output&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;splitlines&lt;/span&gt;&lt;span class=p&gt;():&lt;/span&gt;
        &lt;span class=k&gt;if&lt;/span&gt; &lt;span class=n&gt;ignore_re&lt;/span&gt; &lt;span class=ow&gt;and&lt;/span&gt; &lt;span class=n&gt;ignore_re&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;search&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;line&lt;/span&gt;&lt;span class=p&gt;):&lt;/span&gt;
            &lt;span class=k&gt;continue&lt;/span&gt;
        &lt;span class=k&gt;elif&lt;/span&gt; &lt;span class=s&gt;': '&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=n&gt;line&lt;/span&gt; &lt;span class=ow&gt;and&lt;/span&gt; &lt;span class=n&gt;warning_re&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;search&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;line&lt;/span&gt;&lt;span class=p&gt;):&lt;/span&gt;
            &lt;span class=n&gt;line&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=s&gt;'&lt;/span&gt;&lt;span class=si&gt;%s&lt;/span&gt;&lt;span class=s&gt;: WARNING &lt;/span&gt;&lt;span class=si&gt;%s&lt;/span&gt;&lt;span class=s&gt;'&lt;/span&gt; &lt;span class=o&gt;%&lt;/span&gt; &lt;span class=nb&gt;tuple&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;line&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;split&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=s&gt;': '&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=mi&gt;1&lt;/span&gt;&lt;span class=p&gt;))&lt;/span&gt;
        &lt;span class=k&gt;print&lt;/span&gt; &lt;span class=n&gt;line&lt;/span&gt;

&lt;span class=n&gt;run&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=s&gt;'pyflakes &lt;/span&gt;&lt;span class=si&gt;%s&lt;/span&gt;&lt;span class=s&gt;'&lt;/span&gt; &lt;span class=o&gt;%&lt;/span&gt; &lt;span class=n&gt;sys&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;argv&lt;/span&gt;&lt;span class=p&gt;[&lt;/span&gt;&lt;span class=mi&gt;1&lt;/span&gt;&lt;span class=p&gt;],&lt;/span&gt; &lt;span class=n&gt;pyflakes_ignore&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=n&gt;pyflakes_warning&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
&lt;span class=k&gt;print&lt;/span&gt; &lt;span class=s&gt;'## pyflakes above, pep8 below ##'&lt;/span&gt;
&lt;span class=n&gt;pep8_ignore&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=s&gt;' '&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;join&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=s&gt;'--ignore=&lt;/span&gt;&lt;span class=si&gt;%s&lt;/span&gt;&lt;span class=s&gt;'&lt;/span&gt; &lt;span class=o&gt;%&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=n&gt;pep8_ignore&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
&lt;span class=n&gt;run&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=s&gt;'pep8 &lt;/span&gt;&lt;span class=si&gt;%s&lt;/span&gt;&lt;span class=s&gt; --repeat &lt;/span&gt;&lt;span class=si&gt;%s&lt;/span&gt;&lt;span class=s&gt;'&lt;/span&gt; &lt;span class=o&gt;%&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;pep8_ignore&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=n&gt;sys&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;argv&lt;/span&gt;&lt;span class=p&gt;[&lt;/span&gt;&lt;span class=mi&gt;1&lt;/span&gt;&lt;span class=p&gt;]),&lt;/span&gt; &lt;span class=bp&gt;None&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=n&gt;pep8_warning&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This code may change over time, as I find different outputs that should be
treated as warnings. The latest version of this code is &lt;a class="reference external" href=https://bitbucket.org/keegan_csmith/dotfiles/raw/tip/misc/pyflakespep8.py&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is the snippet of elisp to make flymake use the above command in
python-mode. Replace &lt;cite&gt;/PATH/TO/pyflakespep8.py&lt;/cite&gt; to a valid path to the
command.&lt;/p&gt;
&lt;div class=highlight-scheme&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=c1&gt;;; Pyflakes for python&lt;/span&gt;
&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nf&gt;when&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nb&gt;load &lt;/span&gt;&lt;span class=s&gt;"flymake"&lt;/span&gt; &lt;span class=nv&gt;t&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
  &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nf&gt;defun&lt;/span&gt; &lt;span class=nv&gt;flymake-pychecker-init&lt;/span&gt; &lt;span class=p&gt;()&lt;/span&gt;
    &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=k&gt;let* &lt;/span&gt;&lt;span class=p&gt;((&lt;/span&gt;&lt;span class=nf&gt;temp-file&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nf&gt;flymake-init-create-temp-buffer-copy&lt;/span&gt;
                       &lt;span class=ss&gt;'flymake-create-temp-inplace&lt;/span&gt;&lt;span class=p&gt;))&lt;/span&gt;
           &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nf&gt;local-file&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nf&gt;file-relative-name&lt;/span&gt;
                        &lt;span class=nv&gt;temp-file&lt;/span&gt;
                        &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nf&gt;file-name-directory&lt;/span&gt; &lt;span class=nv&gt;buffer-file-name&lt;/span&gt;&lt;span class=p&gt;))))&lt;/span&gt;
      &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nb&gt;list &lt;/span&gt;&lt;span class=s&gt;"/PATH/TO/pyflakespep8.py"&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nb&gt;list &lt;/span&gt;&lt;span class=nv&gt;local-file&lt;/span&gt;&lt;span class=p&gt;))))&lt;/span&gt;
  &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nf&gt;add-to-list&lt;/span&gt; &lt;span class=ss&gt;'flymake-allowed-file-name-masks&lt;/span&gt;
               &lt;span class=o&gt;'&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=s&gt;"\\.py\\'"&lt;/span&gt; &lt;span class=nv&gt;flymake-pychecker-init&lt;/span&gt;&lt;span class=p&gt;)))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><pubDate>Tue, 18 Oct 2011 18:30:00 -0000</pubDate><guid>http://people.cs.uct.ac.za/~ksmith/2011/better-python-flymake-integration-in-emacs.html</guid></item><item><title>Labelled Breaks in Python with Context Managers</title><link>http://people.cs.uct.ac.za/~ksmith/2011/labelled-break-with-contex-manager.html</link><description>&lt;div class=section id=labelled-breaks-in-python-with-context-managers&gt;
&lt;h1&gt;Labelled Breaks in Python with Context Managers&lt;/h1&gt;
&lt;p&gt;A friend of mine who codes in Java a lot was lamenting the fact that Python
does not support labelled breaks. Labelled breaks are useful when you have
nested loops and want to break out of the outer loop based on a condition in
an inner loop.&lt;/p&gt;
&lt;p&gt;For example say we had a list of lists containing numbers&lt;/p&gt;
&lt;div class=highlight-python&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=kn&gt;import&lt;/span&gt; &lt;span class=nn&gt;random&lt;/span&gt;
&lt;span class=n&gt;lists&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=p&gt;[[&lt;/span&gt;&lt;span class=n&gt;random&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;randint&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=mi&gt;0&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=mi&gt;100&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=nb&gt;range&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=mi&gt;10&lt;/span&gt;&lt;span class=p&gt;)]&lt;/span&gt; &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=nb&gt;range&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=mi&gt;10&lt;/span&gt;&lt;span class=p&gt;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We then want to check if the number 42 is in any of the lists&lt;/p&gt;
&lt;div class=highlight-python&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=n&gt;found&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=bp&gt;False&lt;/span&gt;
&lt;span class=k&gt;for&lt;/span&gt; &lt;span class=n&gt;li&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=n&gt;lists&lt;/span&gt;&lt;span class=p&gt;:&lt;/span&gt;
    &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=n&gt;val&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=n&gt;li&lt;/span&gt;&lt;span class=p&gt;:&lt;/span&gt;
        &lt;span class=k&gt;if&lt;/span&gt; &lt;span class=n&gt;val&lt;/span&gt; &lt;span class=o&gt;==&lt;/span&gt; &lt;span class=mi&gt;42&lt;/span&gt;&lt;span class=p&gt;:&lt;/span&gt;
            &lt;span class=n&gt;found&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=bp&gt;True&lt;/span&gt;
            &lt;span class=k&gt;break&lt;/span&gt;
    &lt;span class=k&gt;if&lt;/span&gt; &lt;span class=n&gt;found&lt;/span&gt;&lt;span class=p&gt;:&lt;/span&gt;
        &lt;span class=k&gt;break&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For the purpose of illustration we use nested for loops instead of something
like&lt;/p&gt;
&lt;div class=highlight-python&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=n&gt;found&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=nb&gt;any&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=mi&gt;42&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=n&gt;li&lt;/span&gt; &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=n&gt;li&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=n&gt;lists&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The two for loops are a simple example, but in more complicated examples we
may have extremely nested loops. This usually calls for some refactoring into
classes/function, but with labelled breaks we can keep a clean code
structure. For example in Java we could write this as&lt;/p&gt;
&lt;div class=highlight-java&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=c1&gt;// int lists[][] = something;&lt;/span&gt;
&lt;span class=kt&gt;boolean&lt;/span&gt; &lt;span class=n&gt;found&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=kc&gt;false&lt;/span&gt;&lt;span class=o&gt;;&lt;/span&gt;

&lt;span class=nl&gt;search:&lt;/span&gt;
&lt;span class=k&gt;for&lt;/span&gt; &lt;span class=o&gt;(&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=mi&gt;0&lt;/span&gt;&lt;span class=o&gt;;&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&lt;/span&gt; &lt;span class=n&gt;lists&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=na&gt;length&lt;/span&gt;&lt;span class=o&gt;;&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt;&lt;span class=o&gt;++)&lt;/span&gt; &lt;span class=o&gt;{&lt;/span&gt;
    &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=o&gt;(&lt;/span&gt;&lt;span class=n&gt;j&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=mi&gt;0&lt;/span&gt;&lt;span class=o&gt;;&lt;/span&gt; &lt;span class=n&gt;j&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&lt;/span&gt; &lt;span class=n&gt;lists&lt;/span&gt;&lt;span class=o&gt;[&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt;&lt;span class=o&gt;].&lt;/span&gt;&lt;span class=na&gt;length&lt;/span&gt;&lt;span class=o&gt;;&lt;/span&gt; &lt;span class=n&gt;j&lt;/span&gt;&lt;span class=o&gt;++)&lt;/span&gt; &lt;span class=o&gt;{&lt;/span&gt;
        &lt;span class=k&gt;if&lt;/span&gt; &lt;span class=o&gt;(&lt;/span&gt;&lt;span class=n&gt;lists&lt;/span&gt;&lt;span class=o&gt;[&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt;&lt;span class=o&gt;][&lt;/span&gt;&lt;span class=n&gt;j&lt;/span&gt;&lt;span class=o&gt;]&lt;/span&gt; &lt;span class=o&gt;==&lt;/span&gt; &lt;span class=mi&gt;42&lt;/span&gt;&lt;span class=o&gt;)&lt;/span&gt; &lt;span class=o&gt;{&lt;/span&gt;
            &lt;span class=n&gt;found&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=kc&gt;true&lt;/span&gt;&lt;span class=o&gt;;&lt;/span&gt;
            &lt;span class=k&gt;break&lt;/span&gt; &lt;span class=n&gt;search&lt;/span&gt;&lt;span class=o&gt;;&lt;/span&gt;
        &lt;span class=o&gt;}&lt;/span&gt;
    &lt;span class=o&gt;}&lt;/span&gt;
&lt;span class=o&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;There is &lt;a class="reference external" href=http://www.python.org/dev/peps/pep-3136/&gt;PEP 3136&lt;/a&gt; which proposed
labelled breaks for Python, but that was rejected. Luckily Python 2.5
introduced context managers, which give us a way to hack in labelled breaks.&lt;/p&gt;
&lt;div class=highlight-python&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=k&gt;class&lt;/span&gt; &lt;span class=nc&gt;Label&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=nb&gt;object&lt;/span&gt;&lt;span class=p&gt;):&lt;/span&gt;
    &lt;span class=k&gt;class&lt;/span&gt; &lt;span class=nc&gt;__break&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=ne&gt;Exception&lt;/span&gt;&lt;span class=p&gt;):&lt;/span&gt;
        &lt;span class=k&gt;def&lt;/span&gt; &lt;span class=nf&gt;__init__&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=bp&gt;self&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=n&gt;ctx&lt;/span&gt;&lt;span class=p&gt;):&lt;/span&gt;
            &lt;span class=bp&gt;self&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;ctx&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=n&gt;ctx&lt;/span&gt;

    &lt;span class=k&gt;def&lt;/span&gt; &lt;span class=nf&gt;__enter__&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=bp&gt;self&lt;/span&gt;&lt;span class=p&gt;):&lt;/span&gt;
        &lt;span class=k&gt;return&lt;/span&gt; &lt;span class=bp&gt;self&lt;/span&gt;

    &lt;span class=k&gt;def&lt;/span&gt; &lt;span class=nf&gt;__exit__&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=bp&gt;self&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=n&gt;exc_type&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=n&gt;exc_val&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=n&gt;exc_tb&lt;/span&gt;&lt;span class=p&gt;):&lt;/span&gt;
        &lt;span class=k&gt;return&lt;/span&gt; &lt;span class=nb&gt;isinstance&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;exc_val&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=bp&gt;self&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;__break&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=ow&gt;and&lt;/span&gt; &lt;span class=n&gt;exc_val&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;ctx&lt;/span&gt; &lt;span class=ow&gt;is&lt;/span&gt; &lt;span class=bp&gt;self&lt;/span&gt;

    &lt;span class=k&gt;def&lt;/span&gt; &lt;span class=nf&gt;break_&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=bp&gt;self&lt;/span&gt;&lt;span class=p&gt;):&lt;/span&gt;
        &lt;span class=k&gt;raise&lt;/span&gt; &lt;span class=bp&gt;self&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;__break&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=bp&gt;self&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When a context manager’s block has finished executing, the __exit__ method is
called. It is passed exception info (or None if it exited without
exception). When the block is exiting due to an exception Python will look at
the return value of __exit__. If the __exit__ method returns True the
exception is not reraised. If __exit__ returns something else then the
exception is reraised.&lt;/p&gt;
&lt;p&gt;So we can simulate labelled breaks using exceptions and context managers. In
the above code the __exit__ method returns True only when the exception passed
is one thrown from its instance of break_. We can now write our search code
with labelled breaks:&lt;/p&gt;
&lt;div class=highlight-python&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=n&gt;found&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=bp&gt;False&lt;/span&gt;
&lt;span class=k&gt;with&lt;/span&gt; &lt;span class=n&gt;Label&lt;/span&gt;&lt;span class=p&gt;()&lt;/span&gt; &lt;span class=k&gt;as&lt;/span&gt; &lt;span class=n&gt;search&lt;/span&gt;&lt;span class=p&gt;:&lt;/span&gt;
 &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=n&gt;li&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=n&gt;lists&lt;/span&gt;&lt;span class=p&gt;:&lt;/span&gt;
     &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=n&gt;val&lt;/span&gt; &lt;span class=ow&gt;in&lt;/span&gt; &lt;span class=n&gt;li&lt;/span&gt;&lt;span class=p&gt;:&lt;/span&gt;
         &lt;span class=k&gt;if&lt;/span&gt; &lt;span class=n&gt;val&lt;/span&gt; &lt;span class=o&gt;==&lt;/span&gt; &lt;span class=mi&gt;42&lt;/span&gt;&lt;span class=p&gt;:&lt;/span&gt;
             &lt;span class=n&gt;found&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=bp&gt;True&lt;/span&gt;
             &lt;span class=n&gt;search&lt;/span&gt;&lt;span class=o&gt;.&lt;/span&gt;&lt;span class=n&gt;break_&lt;/span&gt;&lt;span class=p&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><pubDate>Sat, 04 Jun 2011 18:30:00 -0000</pubDate><guid>http://people.cs.uct.ac.za/~ksmith/2011/labelled-break-with-contex-manager.html</guid></item><item><title>Sliding Window Minimum</title><link>http://people.cs.uct.ac.za/~ksmith/2011/sliding-window-minimum.html</link><description>&lt;div class=section id=sliding-window-minimum&gt;
&lt;h1&gt;Sliding Window Minimum&lt;/h1&gt;
&lt;p&gt;Sliding window minimum is an interesting algorithm, so I thought I would
implement it in a bunch of different languages. See
&lt;a class="reference external" href=https://bitbucket.org/keegan_csmith/sliding-window-minimum/src&gt;https://bitbucket.org/keegan_csmith/sliding-window-minimum/src&lt;/a&gt; for
implementations of the algorithm in different programming languages. What
follows is an explanation of the problem and the algorithm.&lt;/p&gt;
&lt;div class=section id=problem-introduction&gt;
&lt;h2&gt;Problem Introduction&lt;/h2&gt;
&lt;p&gt;The algorithm is sometimes also referred to as the Ascending Minima
algorithm. I learnt the algorithm from a South African Computer Olympiad camp
some years ago. I couldn’t find any references to it in any journal, however
there are some explanations on the Internet.&lt;/p&gt;
&lt;p&gt;Given an array ARR and an integer K, the problem boils down to computing for
each index i: min(ARR[i], ARR[i-1], ..., ARR[i-K+1]). The algorithm for this
“slides” a “window” of size K over ARR computing at each step the current
minimum. In other words the algorithm roughly follows this psuedocode:&lt;/p&gt;
&lt;div class=highlight-python&gt;&lt;pre&gt;for (i = 0; i &amp;lt; ARR.size(); i++) {
  remove ARR[i-K] from the sliding window
  insert ARR[i] into the sliding window
  output the smallest value in the window
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The sliding window algorithm does the remove, insert and output step in
amortized constant time. Or rather the time it takes to run the algorithm is
O(ARR.size()).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=section id=naive-algorithms&gt;
&lt;h2&gt;Naive Algorithms&lt;/h2&gt;
&lt;p&gt;Before I explain the O(1) solution for sliding window minimum, let me explain
some alternative solutions which are suboptimal. The most straight-forward
solution is for each index i in ARR, simply loop over the values from
ARR[i-K+1] to ARR[i] and keep track of the minimum&lt;/p&gt;
&lt;div class=highlight-c++&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=kt&gt;void&lt;/span&gt; &lt;span class=n&gt;brute_force_time&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;vector&lt;/span&gt;&lt;span class=o&gt;&amp;lt;&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt;&lt;span class=o&gt;&amp;gt;&lt;/span&gt; &lt;span class=o&gt;&amp;amp;&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=kt&gt;int&lt;/span&gt; &lt;span class=n&gt;K&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=p&gt;{&lt;/span&gt;
  &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=mi&gt;0&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;size&lt;/span&gt;&lt;span class=p&gt;();&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt;&lt;span class=o&gt;++&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=p&gt;{&lt;/span&gt;
     &lt;span class=kt&gt;int&lt;/span&gt; &lt;span class=n&gt;min_value&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;[&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt;&lt;span class=p&gt;];&lt;/span&gt;
     &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt; &lt;span class=n&gt;j&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;-&lt;/span&gt; &lt;span class=mi&gt;1&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt; &lt;span class=n&gt;j&lt;/span&gt; &lt;span class=o&gt;&amp;gt;=&lt;/span&gt; &lt;span class=n&gt;min&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;-&lt;/span&gt; &lt;span class=n&gt;K&lt;/span&gt; &lt;span class=o&gt;+&lt;/span&gt; &lt;span class=mi&gt;1&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=mi&gt;0&lt;/span&gt;&lt;span class=p&gt;);&lt;/span&gt; &lt;span class=n&gt;j&lt;/span&gt;&lt;span class=o&gt;--&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
        &lt;span class=n&gt;min_value&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=n&gt;min&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;min_value&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;[&lt;/span&gt;&lt;span class=n&gt;j&lt;/span&gt;&lt;span class=p&gt;]);&lt;/span&gt;
     &lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;cout&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=n&gt;min_value&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=sc&gt;' '&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt;
  &lt;span class=p&gt;}&lt;/span&gt;
&lt;span class=p&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The above C++ code runs in O(NK) where N = ARR.size(). We can improve on this
by using a sorted set to speed up the minimum value queries to logarithmic
time&lt;/p&gt;
&lt;div class=highlight-c++&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=kt&gt;void&lt;/span&gt; &lt;span class=n&gt;logarithmic_time&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;vector&lt;/span&gt;&lt;span class=o&gt;&amp;lt;&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt;&lt;span class=o&gt;&amp;gt;&lt;/span&gt; &lt;span class=o&gt;&amp;amp;&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=kt&gt;int&lt;/span&gt; &lt;span class=n&gt;K&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=p&gt;{&lt;/span&gt;
  &lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;multiset&lt;/span&gt;&lt;span class=o&gt;&amp;lt;&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt;&lt;span class=o&gt;&amp;gt;&lt;/span&gt; &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt;
  &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=mi&gt;0&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;size&lt;/span&gt;&lt;span class=p&gt;();&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt;&lt;span class=o&gt;++&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=p&gt;{&lt;/span&gt;
     &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;insert&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;[&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt;&lt;span class=p&gt;]);&lt;/span&gt;
     &lt;span class=k&gt;if&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;-&lt;/span&gt; &lt;span class=n&gt;K&lt;/span&gt; &lt;span class=o&gt;&amp;gt;=&lt;/span&gt; &lt;span class=mi&gt;0&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
       &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;erase&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;find&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;[&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;-&lt;/span&gt; &lt;span class=n&gt;K&lt;/span&gt;&lt;span class=p&gt;]));&lt;/span&gt;
     &lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;cout&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=o&gt;*&lt;/span&gt;&lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;begin&lt;/span&gt;&lt;span class=p&gt;()&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=sc&gt;' '&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt;
  &lt;span class=p&gt;}&lt;/span&gt;
&lt;span class=p&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The window can have at most K elements, so the multiset insert, find and begin
operations all take time O(logK). This gives us an overall time of O(NlogK).&lt;/p&gt;
&lt;p&gt;We can improve the run-time by a constant factor by using a heap instead. All
the heap operations (except finding the minima) have the same run-time
complexity as the multiset versions, however heaps empirically perform
better. We need to be able to remove arbitrary items in the heap, but the
implementation of heaps in C++ (std::priority_queue) does not support this
operation. Luckily a technique I have mastered in real life helps us get
around this: we delete lazily. For each element in the priority queue we also
store what index it was inserted from. Then when we query what the smallest
element is, we discard it if its index falls out of range of our current
window.&lt;/p&gt;
&lt;div class=highlight-c++&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=kt&gt;void&lt;/span&gt; &lt;span class=n&gt;logarithmic_time2&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;vector&lt;/span&gt;&lt;span class=o&gt;&amp;lt;&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt;&lt;span class=o&gt;&amp;gt;&lt;/span&gt; &lt;span class=o&gt;&amp;amp;&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=kt&gt;int&lt;/span&gt; &lt;span class=n&gt;K&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=p&gt;{&lt;/span&gt;
  &lt;span class=c1&gt;// pair&amp;lt;int, int&amp;gt; represents the pair (-ARR[i], i). We use -ARR[i] since&lt;/span&gt;
  &lt;span class=c1&gt;// priority_queue is by default a max-heap, but we want a min-heap. By&lt;/span&gt;
  &lt;span class=c1&gt;// negating the value on insertion and removal we get a min-heap. One can&lt;/span&gt;
  &lt;span class=c1&gt;// also use the rather ugly&lt;/span&gt;
  &lt;span class=c1&gt;// std::priority_queue&amp;lt; std::pair&amp;lt;int, int&amp;gt;,&lt;/span&gt;
  &lt;span class=c1&gt;//                      std::vector&amp;lt; std::pair&amp;lt;int, int&amp;gt; &amp;gt;,&lt;/span&gt;
  &lt;span class=c1&gt;//                      std::greater&amp;lt; std::pair&amp;lt;int, int&amp;gt; &amp;gt; &amp;gt;&lt;/span&gt;

  &lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;priority_queue&lt;/span&gt;&lt;span class=o&gt;&amp;lt;&lt;/span&gt; &lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;pair&lt;/span&gt;&lt;span class=o&gt;&amp;lt;&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=kt&gt;int&lt;/span&gt;&lt;span class=o&gt;&amp;gt;&lt;/span&gt; &lt;span class=o&gt;&amp;gt;&lt;/span&gt; &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt;
  &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=mi&gt;0&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;size&lt;/span&gt;&lt;span class=p&gt;();&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt;&lt;span class=o&gt;++&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=p&gt;{&lt;/span&gt;
     &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;push&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;make_pair&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=o&gt;-&lt;/span&gt;&lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;[&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt;&lt;span class=p&gt;],&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt;&lt;span class=p&gt;));&lt;/span&gt;
     &lt;span class=k&gt;while&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;top&lt;/span&gt;&lt;span class=p&gt;().&lt;/span&gt;&lt;span class=n&gt;second&lt;/span&gt; &lt;span class=o&gt;&amp;lt;=&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;-&lt;/span&gt; &lt;span class=n&gt;K&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
       &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;pop&lt;/span&gt;&lt;span class=p&gt;();&lt;/span&gt;
     &lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;cout&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=o&gt;-&lt;/span&gt;&lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;top&lt;/span&gt;&lt;span class=p&gt;().&lt;/span&gt;&lt;span class=n&gt;first&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=sc&gt;' '&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt;
  &lt;span class=p&gt;}&lt;/span&gt;
&lt;span class=p&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that deleting lazily can actually make this algorithm perform rather
badly. If the input is N values from N to 1, then a value is never deleted
from the priority queue leading to O(logN) insertions. However, on average
this is empirically faster than the multiset version.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=section id=sliding-window-minimum-algorithm&gt;
&lt;h2&gt;Sliding Window Minimum Algorithm&lt;/h2&gt;
&lt;p&gt;The idea of lazily deleting elements is a salient one, but by putting in a bit
more effort when inserting an element into the window we can get amortized
O(1) run-time. Say our window contains the elements {1, 6, 7, 2, 4, 2}. We
want to add the element 5 to our window. Notice that all elements in the
window greater than 5 will now never be the minimum in the window for future i
values, so we might as well get rid of them. The trick to this is to store the
numbers in a deque &lt;a class=footnote-reference href=http://people.cs.uct.ac.za/~ksmith/2011/sliding-window-minimum.html#id2 id=id1&gt;[1]&lt;/a&gt; and whenever inserting a number x we remove all
numbers at the back of the deque which are greater than equal to x. Notice
that if the deque was sorted before inserting, it will still be sorted after
inserting x. Since the deque starts off sorted, it remains sorted throughout
the sliding window algorithm. So the front of the deque will always be the
smallest value.&lt;/p&gt;
&lt;p&gt;The front of the queue might have a value which shouldn’t be in the window
anymore, but we can use the lazy delete idea with the deques as well. Now each
element of ARR is inserted into the deque and deleted from the deque at most
once. This gives as a total run-time of O(N) for the algorithm (amortized O(1)
per insertion/deletion). Pretty sweet&lt;/p&gt;
&lt;div class=highlight-c++&gt;&lt;div class=highlight&gt;&lt;pre&gt;&lt;span class=kt&gt;void&lt;/span&gt; &lt;span class=n&gt;sliding_window_minimum&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;vector&lt;/span&gt;&lt;span class=o&gt;&amp;lt;&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt;&lt;span class=o&gt;&amp;gt;&lt;/span&gt; &lt;span class=o&gt;&amp;amp;&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=kt&gt;int&lt;/span&gt; &lt;span class=n&gt;K&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=p&gt;{&lt;/span&gt;
  &lt;span class=c1&gt;// pair&amp;lt;int, int&amp;gt; represents the pair (ARR[i], i)&lt;/span&gt;
  &lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;deque&lt;/span&gt;&lt;span class=o&gt;&amp;lt;&lt;/span&gt; &lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;pair&lt;/span&gt;&lt;span class=o&gt;&amp;lt;&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt;&lt;span class=p&gt;,&lt;/span&gt; &lt;span class=kt&gt;int&lt;/span&gt;&lt;span class=o&gt;&amp;gt;&lt;/span&gt; &lt;span class=o&gt;&amp;gt;&lt;/span&gt; &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt;
  &lt;span class=k&gt;for&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=kt&gt;int&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;=&lt;/span&gt; &lt;span class=mi&gt;0&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;size&lt;/span&gt;&lt;span class=p&gt;();&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt;&lt;span class=o&gt;++&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=p&gt;{&lt;/span&gt;
     &lt;span class=k&gt;while&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=o&gt;!&lt;/span&gt;&lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;empty&lt;/span&gt;&lt;span class=p&gt;()&lt;/span&gt; &lt;span class=o&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;back&lt;/span&gt;&lt;span class=p&gt;().&lt;/span&gt;&lt;span class=n&gt;first&lt;/span&gt; &lt;span class=o&gt;&amp;gt;=&lt;/span&gt; &lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;[&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt;&lt;span class=p&gt;])&lt;/span&gt;
       &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;pop_back&lt;/span&gt;&lt;span class=p&gt;();&lt;/span&gt;
     &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;push_back&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;make_pair&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;ARR&lt;/span&gt;&lt;span class=p&gt;[&lt;/span&gt;&lt;span class=n&gt;i&lt;/span&gt;&lt;span class=p&gt;],&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt;&lt;span class=p&gt;));&lt;/span&gt;

     &lt;span class=k&gt;while&lt;/span&gt;&lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;front&lt;/span&gt;&lt;span class=p&gt;().&lt;/span&gt;&lt;span class=n&gt;second&lt;/span&gt; &lt;span class=o&gt;&amp;lt;=&lt;/span&gt; &lt;span class=n&gt;i&lt;/span&gt; &lt;span class=o&gt;-&lt;/span&gt; &lt;span class=n&gt;K&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt;
       &lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;pop_front&lt;/span&gt;&lt;span class=p&gt;();&lt;/span&gt;

     &lt;span class=n&gt;std&lt;/span&gt;&lt;span class=o&gt;::&lt;/span&gt;&lt;span class=n&gt;cout&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=p&gt;(&lt;/span&gt;&lt;span class=n&gt;window&lt;/span&gt;&lt;span class=p&gt;.&lt;/span&gt;&lt;span class=n&gt;front&lt;/span&gt;&lt;span class=p&gt;().&lt;/span&gt;&lt;span class=n&gt;first&lt;/span&gt;&lt;span class=p&gt;)&lt;/span&gt; &lt;span class=o&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=sc&gt;' '&lt;/span&gt;&lt;span class=p&gt;;&lt;/span&gt;
  &lt;span class=p&gt;}&lt;/span&gt;
&lt;span class=p&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=section id=extensions&gt;
&lt;h2&gt;Extensions&lt;/h2&gt;
&lt;p&gt;You can modify the algorithm by flipping &amp;gt;= to &amp;lt;= to get the sliding window
maximum algorithm.&lt;/p&gt;
&lt;p&gt;In fact this algorithm works on any totally ordered set. So the elements can
be floats, sets, strings, etc. Essentially anything which has a &amp;lt;= operator
that behaves “nicely”.&lt;/p&gt;
&lt;p&gt;Think you fully understand this algorithm, try solving these problems:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class=simple&gt;
&lt;li&gt;Task “sound” at &lt;a class="reference external" href=http://www.boi2007.de/en/tasks&gt;http://www.boi2007.de/en/tasks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Task “pyramid” at &lt;a class="reference external" href=http://olympiads.win.tue.nl/ioi/ioi2006/contest/day1/&gt;http://olympiads.win.tue.nl/ioi/ioi2006/contest/day1/&lt;/a&gt;
(medium to hard problem)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;table class="docutils footnote" frame=void id=id2 rules=none&gt;
&lt;col class=label&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign=top&gt;
&lt;tr&gt;&lt;td class=label&gt;&lt;a class=fn-backref href=http://people.cs.uct.ac.za/~ksmith/2011/sliding-window-minimum.html#id1&gt;[1]&lt;/a&gt;&lt;td&gt;Double-Ended Queue. Supports constant time insertion, removal and
lookups at the front and the back of the queue.&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
</description><pubDate>Thu, 05 May 2011 12:00:00 -0000</pubDate><guid>http://people.cs.uct.ac.za/~ksmith/2011/sliding-window-minimum.html</guid></item></channel></rss>
