<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>/dev/tty &#187; Eduard Lohmann</title>
	<atom:link href="http://blog.tty.nl/author/eduard/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tty.nl</link>
	<description>Notes on Web Development, Computer Programming, and Software Engineering</description>
	<lastBuildDate>Thu, 29 Dec 2011 10:59:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Splitting a database dump</title>
		<link>http://blog.tty.nl/2011/12/28/splitting-a-database-dump/</link>
		<comments>http://blog.tty.nl/2011/12/28/splitting-a-database-dump/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 12:43:50 +0000</pubDate>
		<dc:creator>Eduard Lohmann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=578</guid>
		<description><![CDATA[This is a way to split a SQL dump into tables that is relatively easy. It should start with zcat FILE.gz &#124; csplit -ftable &#8211; &#8220;/DROP TABLE/&#8221; {*}, but csplit has bug where reading a lot from standard in does &#8230; <a href="http://blog.tty.nl/2011/12/28/splitting-a-database-dump/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is a way to split a SQL dump into tables that is relatively easy.</p>
<p>It should start with zcat FILE.gz | csplit -ftable &#8211; &#8220;/DROP TABLE/&#8221; {*},<br />
but csplit has bug where reading a lot from standard in does not work.<br />
So instead unzip your file first.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">gunzip FILE.gz<br />
csplit -ftable FILE &quot;/DROP TABLE/&quot; {*}</div></div>
<p>Then to give the files meaningful names:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">for FILE in `ls -1 table*`; do <br />
&nbsp; &nbsp; &nbsp;NAME=`head -n1 $FILE | cut -d$'\x60' -f2`<br />
&nbsp; &nbsp; &nbsp;mv $FILE &quot;$NAME.sql&quot;;<br />
done;</div></div>
<p>If your dump does not start witjh a DROP TABLE `name` IF EXISTS,<br />
you will have to change the match expression to csplit a litte.</p>
<p>Hope this is useful to someone.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2011/12/28/splitting-a-database-dump/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Setting up Emacs to compare two git tags</title>
		<link>http://blog.tty.nl/2011/12/09/setting-up-emacs-to-compare-two-git-tags/</link>
		<comments>http://blog.tty.nl/2011/12/09/setting-up-emacs-to-compare-two-git-tags/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 11:30:24 +0000</pubDate>
		<dc:creator>Eduard Lohmann</dc:creator>
				<category><![CDATA[Emacs]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=530</guid>
		<description><![CDATA[Introduction This is a setup for using Emacs to compare two git tags. It is based on Ediff mode and Ediff Trees. Ediff Trees is a useful front-end for comparing large trees of files. To make things easier we have &#8230; <a href="http://blog.tty.nl/2011/12/09/setting-up-emacs-to-compare-two-git-tags/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>This is a setup for using Emacs to compare two git tags.  It is based on <a href="//www.emacswiki.org/emacs/EdiffMode" title="Ediff mode">Ediff mode</a> and <a href="http://www.emacswiki.org/emacs/EdiffTrees" title="Ediff Trees">Ediff Trees</a>. Ediff Trees is a useful front-end for comparing large trees of files. To make things easier we have two git clones, one for each tag that we call before and after.</p>
<h2>Needed Code</h2>
<p>Create a file named ediff-trees.el with the following contents and place it in your Emacs load path:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">;;; ediff-trees.el --- Recursively ediff two directory trees<br />
;;;----------------------------------------------------------------------<br />
;; Author: Joao Cachopo &lt;joao.cachopo@inesc-id.pt&gt;<br />
;; Created on: Wed May 10 17:30:49 2006<br />
;; Keywords: ediff, comparing<br />
;; Version: 20071126.1<br />
;;<br />
;; Copyright (C) 2006 Joao Cachopo<br />
<br />
;; This program is not part of GNU Emacs<br />
<br />
;; This program is free software; you can redistribute it and/or<br />
;; modify it under the terms of the GNU General Public License as<br />
;; published by the Free Software Foundation; either version 2, or (at<br />
;; your option) any later version.<br />
<br />
;; This program is distributed in the hope that it will be useful, but<br />
;; WITHOUT ANY WARRANTY; without even the implied warranty of<br />
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. &nbsp;See the GNU<br />
;; General Public License for more details.<br />
<br />
;; You should have received a copy of the GNU General Public License<br />
;; along with GNU Emacs; see the file COPYING. &nbsp;If not, write to the<br />
;; Free Software Foundation, 675 Massachusettes Ave, Cambridge, MA<br />
;; 02139, USA.<br />
<br />
;;; Commentary:<br />
<br />
;; The ediff-trees package is a simple frontend to the emacs' ediff<br />
;; package to allow a simpler comparison of two similar directory<br />
;; trees.<br />
<br />
;; I wrote this package because I often need to compare two different<br />
;; versions of the same directory tree and ediff-directories is not<br />
;; very helpful in this case. &nbsp;Specially when the directory trees to<br />
;; compare are deep and only a few files have changed.<br />
;; Typically, that occurs when I create a copy of some project<br />
;; directory tree either to make some experiments myself or to send to<br />
;; someone else that will return a modified directory tree to me<br />
;; later. &nbsp;(Yes, I heard of version control systems, and I use them<br />
;; regularly. &nbsp;Yet, for several reasons, sometimes that is not an<br />
;; option.)<br />
<br />
;; Later, when I want to integrate the modified directory tree with<br />
;; the original tree, I want to see the differences to the original<br />
;; version, so that I may decide whether to accept the changes or not.<br />
;; This is where this package kicks in...<br />
<br />
;; To use it, just call `ediff-trees', which will ask for two<br />
;; directories to compare. &nbsp;Usually, I give the original directory as<br />
;; the first one and the modified directory as the second one.<br />
<br />
;; ediff-trees recursively descends both directories, collecting the<br />
;; pairs of files that are worth &quot;comparing&quot;: either files that<br />
;; changed, or that appear in one of the two directory trees but not<br />
;; in the other. &nbsp;Then, it shows the first &quot;change&quot; using ediff.<br />
<br />
;; In fact, ediff-trees either uses ediff to compare a file with its<br />
;; changed version, or simply opens a file that occurs in only one of<br />
;; the trees.<br />
<br />
;; The user can then navigate backward and forward in the set of<br />
;; changes by using `ediff-trees-examine-next' and<br />
;; `ediff-trees-examine-previous', respectively. &nbsp;These functions move<br />
;; from one change (quiting the current ediff session or killing the<br />
;; current file buffer) to another. &nbsp;Therefore, by repeatedly using<br />
;; these functions we can go through all the changes. &nbsp;I usually use<br />
;; some global bindings for these functions. &nbsp;Something like this:<br />
;;<br />
;; &nbsp; (global-set-key (kbd &quot;s-SPC&quot;) 'ediff-trees-examine-next)<br />
;; &nbsp; (global-set-key (kbd &quot;S-s-SPC&quot;) 'ediff-trees-examine-previous)<br />
;; &nbsp; (global-set-key (kbd &quot;C-s-SPC&quot;) 'ediff-trees-examine-next-regexp)<br />
;; &nbsp; (global-set-key (kbd &quot;C-S-s-SPC&quot;) 'ediff-trees-examine-previous-regexp))<br />
<br />
;; The `ediff-trees-examine-next-regexp' and<br />
;; `ediff-trees-examine-previous-regexp' skip over the list of changes<br />
;; to a file with a filename that matches a given regexp.<br />
<br />
;; This package allows for some customization. &nbsp;Please, see the<br />
;; ediff-trees group under customize.<br />
<br />
;; Finally, to deal with small changes in the white space I often find<br />
;; it useful to configure ediff like this:<br />
;;<br />
;; &nbsp; (setq ediff-diff-options &quot;-w&quot;)<br />
;; &nbsp; (setq-default ediff-ignore-similar-regions t)<br />
<br />
;;; Code:<br />
<br />
<br />
(require 'ediff)<br />
<br />
(defgroup ediff-trees nil<br />
&nbsp; &quot;Extend ediff to allow comparing two trees recursively.&quot;<br />
&nbsp; :tag &quot;Ediff Trees&quot;<br />
&nbsp; :group 'ediff)<br />
<br />
<br />
(defface ediff-trees-deleted-original-face<br />
&nbsp; '((((class color))<br />
&nbsp; &nbsp; &nbsp;(:background &quot;Pink&quot;))<br />
&nbsp; &nbsp; (t (:inverse-video t)))<br />
&nbsp; &quot;Face for highlighting the buffer when it was deleted from the original tree.&quot;<br />
&nbsp; :group 'ediff-trees)<br />
<br />
(defcustom ediff-trees-file-ignore-regexp<br />
&nbsp; &quot;\\`\\(\\.?#.*\\|.*,v\\|.*~\\|CVS\\|_darcs\\)\\'&quot;<br />
&nbsp; &quot;A regexp matching either files or directories to be ignored<br />
when comparing two trees. &nbsp;If a directory matches the regexp,<br />
then its contents is not scanned by `ediff-trees'.&quot;<br />
&nbsp; :type 'regexp<br />
&nbsp; :group 'ediff-trees)<br />
<br />
<br />
(defcustom ediff-trees-sort-order-regexps nil<br />
&nbsp; &quot;*Specifies a list of regexps that determine the order in which<br />
files will be presented during the ediff-trees session. &nbsp;Files<br />
with filenames matching former regexps appear earlier in the<br />
session. &nbsp;If a filename matches more than one regexp, the first<br />
one wins.&quot;<br />
&nbsp; :type '(repeat regexp)<br />
&nbsp; :group 'ediff-trees)<br />
<br />
<br />
<br />
(defun ediff-trees (root1 root2)<br />
&nbsp; &quot;Starts a new ediff session that recursively compares two<br />
trees.&quot;<br />
&nbsp; (interactive<br />
&nbsp; &nbsp;(let ((dir-A (ediff-get-default-directory-name))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;f)<br />
&nbsp; &nbsp; &nbsp;(list (setq f (ediff-read-file-name &quot;Directory A to compare:&quot; dir-A nil))<br />
&nbsp; &nbsp; &nbsp; &nbsp;(ediff-read-file-name &quot;Directory B to compare:&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(if ediff-use-last-dir<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ediff-last-dir-B<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(ediff-strip-last-dir f))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nil))))<br />
&nbsp; (ediff-trees-internal root1 root2))<br />
<br />
<br />
;;; Internal variables, used during an ediff-trees session<br />
(defvar ediff-trees-current-file nil)<br />
(defvar ediff-trees-remaining-files (list))<br />
(defvar ediff-trees-examined-files (list))<br />
<br />
<br />
(defun ediff-trees-internal (root1 root2)<br />
&nbsp; (let ((files-changed (ediff-trees-collect-files root1 root2)))<br />
&nbsp; &nbsp; (if (not (null files-changed))<br />
&nbsp; &nbsp; &nbsp; &nbsp; (progn<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (setq ediff-trees-remaining-files files-changed)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (setq ediff-trees-examined-files (list))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (ediff-trees-examine-next 1))<br />
&nbsp; &nbsp; &nbsp; (message &quot;There are no changes between the trees!&quot;))))<br />
<br />
(defun ediff-trees-collect-files (root1 root2)<br />
&nbsp; (ediff-trees-sort-files<br />
&nbsp; &nbsp;(nconc (ediff-trees-collect-changed-files root1 root2)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (mapcar (lambda (el) (cons el nil))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (ediff-trees-collect-new-files root1 root2))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (mapcar (lambda (el) (cons nil el))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (ediff-trees-collect-new-files root2 root1)))))<br />
<br />
<br />
(defun ediff-trees-sort-files (files)<br />
&nbsp; (let ((tagged-files (mapcar (lambda (pair)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (cons (ediff-trees-get-sort-order (or (car pair) (cdr pair)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pair))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; files)))<br />
&nbsp; &nbsp; (mapcar #'cdr<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (sort tagged-files<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (lambda (tf1 tf2)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (let ((order1 (car tf1))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (order2 (car tf2)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (or (&lt; order1 order2)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (and (= order1 order2)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(let ((el1 (or (cadr tf1) (cddr tf1)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(el2 (or (cadr tf2) (cddr tf2))))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(string&lt; el1 el2))))))))))<br />
<br />
<br />
(defun ediff-trees-get-sort-order (pathname)<br />
&nbsp; (let ((order 0)<br />
&nbsp; &nbsp; &nbsp; &nbsp; (sorting-regexps ediff-trees-sort-order-regexps))<br />
&nbsp; &nbsp; (while (and (not (null sorting-regexps))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (not (string-match (pop sorting-regexps) pathname)))<br />
&nbsp; &nbsp; &nbsp; (setq order (+ order 1)))<br />
&nbsp; &nbsp; order))<br />
<br />
<br />
<br />
(defun ediff-trees-collect-changed-files (root1 root2)<br />
&nbsp; (let ((changed (list)))<br />
&nbsp; &nbsp; (dolist (filename (directory-files root1))<br />
&nbsp; &nbsp; &nbsp; (unless (ediff-trees-skip-file-p filename)<br />
&nbsp; &nbsp; &nbsp; &nbsp; (let ((file1 (expand-file-name filename root1))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (file2 (expand-file-name filename root2)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (when (and (file-exists-p file1) (file-exists-p file2))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (if (eql (file-directory-p file1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(file-directory-p file2))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (cond ((file-directory-p file1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(setq changed (nconc changed (ediff-trees-collect-changed-files file1 file2))))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((not (ediff-same-file-contents file1 file2))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(push (cons file1 file2) changed)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (let ((msg (format &quot;I cannot compare a directory, '%s', with a file. &nbsp;Continue? &quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(if (file-directory-p file1) file1 file2))))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (if (not (y-or-n-p msg))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (error &quot;Aborting ediff-trees&quot;))))))))<br />
&nbsp; &nbsp; changed))<br />
<br />
<br />
(defun ediff-trees-collect-new-files (root1 root2)<br />
&nbsp; &quot;Collect files from root1 that do not appear at root2.&quot;<br />
&nbsp; (let ((new-files (list)))<br />
&nbsp; &nbsp; (dolist (filename (directory-files root1))<br />
&nbsp; &nbsp; &nbsp; (unless (ediff-trees-skip-file-p filename)<br />
&nbsp; &nbsp; &nbsp; &nbsp; (let ((file1 (expand-file-name filename root1))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (file2 (and root2 (expand-file-name filename root2))))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (when (file-exists-p file1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (cond ((file-directory-p file1)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(setq new-files<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(nconc new-files<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (ediff-trees-collect-new-files file1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(and (stringp file2)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (file-directory-p file2)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; file2)))))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((or (null file2) (not (file-exists-p file2)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(push file1 new-files)))))))<br />
&nbsp; &nbsp; new-files))<br />
<br />
(defun ediff-trees-skip-file-p (filename)<br />
&nbsp; ;; always ignore . and ..<br />
&nbsp; (or (string= filename &quot;.&quot;)<br />
&nbsp; &nbsp; &nbsp; (string= filename &quot;..&quot;)<br />
&nbsp; &nbsp; &nbsp; (string-match ediff-trees-file-ignore-regexp filename)))<br />
<br />
<br />
(defun ediff-trees-examine-next (num)<br />
&nbsp; (interactive &quot;p&quot;)<br />
&nbsp; (if (&lt; num 0)<br />
&nbsp; &nbsp; (ediff-trees-examine-previous (- num))<br />
&nbsp; &nbsp; (ediff-trees-examine-file<br />
&nbsp; &nbsp; &nbsp;(lambda (file) (zerop (setq num (- num 1))))<br />
&nbsp; &nbsp; &nbsp;(lambda (file) (push file ediff-trees-examined-files))<br />
&nbsp; &nbsp; &nbsp;(lambda () (pop ediff-trees-remaining-files)))))<br />
<br />
<br />
(defun ediff-trees-examine-previous (num)<br />
&nbsp; (interactive &quot;p&quot;)<br />
&nbsp; (if (&lt; num 0)<br />
&nbsp; &nbsp; (ediff-trees-examine-next (- num))<br />
&nbsp; &nbsp; (ediff-trees-examine-file<br />
&nbsp; &nbsp; &nbsp;(lambda (file) (zerop (setq num (- num 1))))<br />
&nbsp; &nbsp; &nbsp;(lambda (file) (push file ediff-trees-remaining-files))<br />
&nbsp; &nbsp; &nbsp;(lambda () (pop ediff-trees-examined-files)))))<br />
<br />
<br />
(defun ediff-trees-examine-next-regexp (regexp)<br />
&nbsp; (interactive &quot;sSearch for (regexp): &quot;)<br />
&nbsp; (ediff-trees-examine-file<br />
&nbsp; &nbsp;(lambda (file) (string-match regexp (or (car file) (cdr file))))<br />
&nbsp; &nbsp;(lambda (file) (push file ediff-trees-examined-files))<br />
&nbsp; &nbsp;(lambda () (pop ediff-trees-remaining-files))))<br />
<br />
<br />
(defun ediff-trees-examine-previous-regexp (regexp)<br />
&nbsp; (interactive &quot;sSearch for (regexp): &quot;)<br />
&nbsp; (ediff-trees-examine-file<br />
&nbsp; &nbsp;(lambda (file) (string-match regexp (or (car file) (cdr file))))<br />
&nbsp; &nbsp;(lambda (file) (push file ediff-trees-remaining-files))<br />
&nbsp; &nbsp;(lambda () (pop ediff-trees-examined-files))))<br />
<br />
<br />
(defun ediff-trees-examine-file (pred save-current-file-fn get-next-file-fn)<br />
&nbsp; (when (eq (current-buffer) ediff-control-buffer)<br />
&nbsp; &nbsp; (ediff-really-quit nil))<br />
&nbsp; (unless (null ediff-trees-current-file)<br />
&nbsp; &nbsp; (funcall save-current-file-fn ediff-trees-current-file)<br />
&nbsp; &nbsp; (when (car ediff-trees-current-file)<br />
&nbsp; &nbsp; &nbsp; (kill-buffer (find-buffer-visiting (car ediff-trees-current-file))))<br />
&nbsp; &nbsp; (when (cdr ediff-trees-current-file)<br />
&nbsp; &nbsp; &nbsp; (kill-buffer (find-buffer-visiting (cdr ediff-trees-current-file))))<br />
&nbsp; &nbsp; (setq ediff-trees-current-file nil))<br />
&nbsp; (let ((next-file (ediff-trees-get-next-file pred save-current-file-fn get-next-file-fn)))<br />
&nbsp; &nbsp; (if (null next-file)<br />
&nbsp; &nbsp; &nbsp; &nbsp; (message &quot;No more files.&quot;)<br />
&nbsp; &nbsp; &nbsp; (progn<br />
&nbsp; &nbsp; &nbsp; &nbsp; (setq ediff-trees-current-file next-file)<br />
&nbsp; &nbsp; &nbsp; &nbsp; (if (and (car next-file) (cdr next-file))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (ediff-files (car next-file) (cdr next-file))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (progn<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (delete-other-windows)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (find-file-read-only (or (car next-file) (cdr next-file)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (when (null (cdr next-file))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (let ((overlay (make-overlay 0 (point-max))))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (overlay-put overlay 'face 'ediff-trees-deleted-original-face)))))))))<br />
<br />
<br />
(defun ediff-trees-get-next-file (pred save-current-file-fn get-next-file-fn)<br />
&nbsp; (let ((return-value 'not-found))<br />
&nbsp; &nbsp; (while (eq return-value 'not-found)<br />
&nbsp; &nbsp; &nbsp; (let ((next-file (funcall get-next-file-fn)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; (cond ((null next-file)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(setq return-value nil))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((funcall pred next-file)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(setq return-value next-file))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (t<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(funcall save-current-file-fn next-file)))))<br />
&nbsp; &nbsp; return-value))<br />
<br />
<br />
(provide 'ediff-trees)</div></div>
<p>This code can be downloaded from <a href="http://www.emacswiki.org/emacs/ediff-trees.el" title="Ediff Trees">the EmacsWiki</a>. We made a change in the two functions ediff-trees-collect-changed-files and ediff-trees-collect-new-files where we added condition (file-exists-p file1) to skip symbolic links that do not refer to an existing file.</p>
<p>Create another file with the following contents, place it in your Emacs load path and load it:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">(assert (and (boundp 'ediff-git-root-before) (stringp ediff-git-root-before)))<br />
(assert (and (boundp 'ediff-git-root-after) &nbsp;(stringp ediff-git-root-after)))<br />
<br />
(require 'ediff-trees)<br />
<br />
(setq-default ediff-ignore-similar-regions t)<br />
(setq-default ediff-split-window-function 'split-window-horizontally)<br />
(setq-default ediff-trees-file-ignore-regexp &quot;^[.]?#\\|~$\\|^[.]git$&quot;)<br />
<br />
(defun next-error-capable-buffer () &quot;Return a 'next-error' capable buffer.&quot;<br />
&nbsp; (ignore-errors (next-error-find-buffer))<br />
)<br />
<br />
(defun kill-all-next-error-capable-buffers () &quot;Kill all 'next-error' capable buffers.&quot;<br />
&nbsp; (interactive)<br />
&nbsp; (let ((buffer (next-error-capable-buffer)))<br />
&nbsp; &nbsp; (when buffer<br />
&nbsp; &nbsp; &nbsp; (message &quot;Killing buffer '%s'&quot; (buffer-name buffer))<br />
&nbsp; &nbsp; &nbsp; (kill-buffer buffer)<br />
&nbsp; &nbsp; &nbsp; (kill-all-next-error-capable-buffers)<br />
&nbsp; &nbsp; )<br />
&nbsp; )<br />
)<br />
<br />
(defun ediff-git-commits (commits) &quot;Start a new ediff session that recursively compares 'before' and 'after'.&quot;<br />
&nbsp; (interactive &quot;sEnter commit(s): &quot;)<br />
&nbsp; (let* ((whitespace-chars &quot; \f\n\r\t&quot;)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(cc-whitespace (concat &quot;[&quot; whitespace-chars &quot;]&quot;))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(re-commit (concat &quot;\\([^&quot; whitespace-chars &quot;]+\\)&quot;))<br />
&nbsp; &nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; (if (string-match (concat &quot;\\`&quot; cc-whitespace &quot;*&quot; re-commit &quot;\\(?:&quot; cc-whitespace &quot;+&quot; re-commit &quot;\\)?&quot; cc-whitespace &quot;*&quot; &quot;\\'&quot;) commits)<br />
&nbsp; &nbsp; &nbsp; (let ((commit-before (match-string 1 commits)) (commit-after (match-string 2 commits)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; (unless commit-after<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (if (y-or-n-p (format &quot;Compare %s with parent? &quot; commit-before))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (setq commit-after commit-before commit-before (concat commit-after &quot;^&quot;))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (let ((commit (read-string &quot;Enter commit for 'after': &quot;)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (if (string-match (concat &quot;\\`&quot; cc-whitespace &quot;*&quot; re-commit cc-whitespace &quot;*&quot; &quot;\\'&quot;) commit)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (setq commit-after (match-string 1 commit))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (error &quot;Not a valid commit&quot;)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; &nbsp; &nbsp; (let* ((case-fold-search nil) (ok &quot;ok&quot;) (re-command-ok (concat cc-whitespace (regexp-quote ok) &quot;\\'&quot;))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(command-template (concat &quot;unset CDPATH &amp;&amp; cd %s &amp;&amp; git checkout . &amp;&amp; git fetch &amp;&amp; git checkout %s &amp;&amp; echo -n &quot; ok))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(command-before (format command-template ediff-git-root-before commit-before))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(command-after &nbsp;(format command-template ediff-git-root-after commit-after))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (message &quot;Checking out 'before'...&quot;)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (unless (string-match re-command-ok (shell-command-to-string command-before))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (error &quot;Error checking out 'before' (%s)&quot; command-before)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (message &quot;Checking out 'after'...&quot;)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (unless (string-match re-command-ok (shell-command-to-string command-after))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (error &quot;Error checking out 'after' (%s)&quot; command-after)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; &nbsp; (unless (and (string-equal commits &quot;&quot;) (y-or-n-p &quot;No commit(s) supplied. Keep current checkouts? &quot;))<br />
&nbsp; &nbsp; &nbsp; &nbsp; (error &quot;No valid commit(s) supplied&quot;)<br />
&nbsp; &nbsp; &nbsp; )<br />
&nbsp; &nbsp; )<br />
&nbsp; &nbsp; (kill-all-next-error-capable-buffers)<br />
&nbsp; &nbsp; (message &quot;Comparing...&quot;)<br />
&nbsp; &nbsp; (ediff-trees ediff-git-root-before ediff-git-root-after)<br />
&nbsp; )<br />
)<br />
<br />
(defun visit-next (arg) &quot;In an ediff session, visit next file, else visit next 'next-error' message.&quot;<br />
&nbsp; (interactive &quot;p&quot;)<br />
&nbsp; (if (or (next-error-capable-buffer) (null ediff-trees-current-file))<br />
&nbsp; &nbsp; (next-error arg)<br />
&nbsp; &nbsp; (ediff-trees-examine-next arg)<br />
&nbsp; )<br />
)<br />
<br />
(defun visit-previous (arg) &quot;In an ediff session, visit previous file, else visit previous 'next-error' message.&quot;<br />
&nbsp; (interactive &quot;p&quot;)<br />
&nbsp; (if (or (next-error-capable-buffer) (null ediff-trees-current-file))<br />
&nbsp; &nbsp; (previous-error arg)<br />
&nbsp; &nbsp; (ediff-trees-examine-previous arg)<br />
&nbsp; )<br />
)</div></div>
<p>Make sure you have constants ediff-git-root-before and ediff-git-root-after defined in your config.<br />
Example:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">(defconst ediff-git-root-before &quot;/home/eduard/before&quot;)<br />
(defconst ediff-git-root-after &quot;/home/eduard/after&quot;)</div></div>
<h2>Usage</h2>
<p>To start a new ediff session, execute ediff-git-commits (M-x ediff-git-commits) and enter zero, one or two commits. When comparing is done, execute visit-next(or bind it to a key you like), to go to the next differing files.</p>
<p>Harro &#038; Eduard</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2011/12/09/setting-up-emacs-to-compare-two-git-tags/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Perl Quiz, Perl Solution: Plusified Equations</title>
		<link>http://blog.tty.nl/2009/09/11/perl-quiz-perl-solution-plusified-equations/</link>
		<comments>http://blog.tty.nl/2009/09/11/perl-quiz-perl-solution-plusified-equations/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 10:09:41 +0000</pubDate>
		<dc:creator>Eduard Lohmann</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[Perl Quiz of the Week]]></category>

		<guid isPermaLink="false">http://blog.tty.nl/?p=165</guid>
		<description><![CDATA[For problem definition see: The Haskell solution. Because this was a test for an applicant, I felt I should solve it too in order to get a good idea of how difficult it is. My approach was so generate the &#8230; <a href="http://blog.tty.nl/2009/09/11/perl-quiz-perl-solution-plusified-equations/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For problem definition see: <a href="http://blog.tty.nl/2009/08/19/haskell-solution-to-perl-quiz-of-the-week-plusified-equations/">The Haskell solution</a>.</p>
<p>Because this was a test for an applicant, I felt I should solve it too in order to get a good idea of how difficult it is.</p>
<p>My approach was so generate the plussified expressions from smallest to largest sum. That way I can discard any expressions from one list that have a smaller sum then the least sum of the other list.</p>
<h3>The Algorithm</h3>
<ol>
<li>Generate a list of plussified expressions for each of the integers, sorted smallest to largest sum.</li>
<li>Compare the sums of the first elements of both lists. If one is less then the other remove it and repeat.</li>
<li>
<p>If the sums are equal you have found an answer.</p>
<p>You could now drop the first expression of each list and continue,<br />
        but you would miss the answers where you link the current first element of one list with<br />
        expressions in the other list that are not first, but have the same sum.<br />
        Therefore I also explicitly look for those answers with a recursive call.</p>
</li>
</ol>
<p>Questions welcome at eduard@tty.nl .</p>
<div class="codecolorer-container perl default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#!/usr/bin/env perl</span><br />
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span><br />
<br />
main<span style="color: #009900;">&#40;</span> <span style="color: #339933;">@</span><span style="color: #000000; font-weight: bold;">ARGV</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">sub</span> main <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009966; font-style: italic;">/^\d+$/</span> <span style="color: #b1b100;">or</span> <span style="color: #000066;">die</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;'$_' is not a valid string of digits.&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">for</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #cc66cc;">2</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">@_</span> <span style="color: #b1b100;">or</span> <span style="color: #000066;">die</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Supply exactly 2 strings of digits seperated by a space&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@answers</span> <span style="color: #339933;">=</span> find_answers<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#91;</span> plusify<span style="color: #009900;">&#40;</span><span style="color: #000066;">shift</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span> plusify<span style="color: #009900;">&#40;</span><span style="color: #000066;">shift</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">print</span> <span style="color: #000066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">@answers</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Found &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000066;">scalar</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@answers</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">&quot; answers.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066;">return</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">sub</span> plusify &nbsp;<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$num</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$first_digit</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$rest</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$num</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">m/(\d)(\d+)?/</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$first_digit</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">if</span> <span style="color: #b1b100;">not</span> <span style="color: #000066;">defined</span> <span style="color: #0000ff;">$rest</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@ways</span> <span style="color: #339933;">=</span> <span style="color: #000066;">map</span> <span style="color: #009900;">&#123;</span> &nbsp;<span style="color: #0000ff;">$first_digit</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">$_</span> <span style="color: #339933;">,</span> <span style="color: #0000ff;">$first_digit</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'+'</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">$_</span> <span style="color: #009900;">&#125;</span> plusify<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$rest</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066;">return</span> <span style="color: #000066;">sort</span> <span style="color: #009900;">&#123;</span> sum_expression<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$a</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;=&gt;</span> sum_expression<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$b</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span> <span style="color: #0000ff;">@ways</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<br />
<span style="color: #000000; font-weight: bold;">sub</span> sum_expression &nbsp;<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$expression</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sum</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$sum</span> <span style="color: #339933;">+=</span> <span style="color: #0000ff;">$_</span> <span style="color: #b1b100;">for</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">qr</span><span style="color: #009900;">&#123;</span>\<span style="color: #339933;">+</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$expression</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066;">return</span> <span style="color: #0000ff;">$sum</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">sub</span> find_answers &nbsp;<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$expressions_1</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$expressions_2</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@expressions_1</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$expressions_1</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@expressions_2</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$expressions_2</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@answers</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@expressions_1</span> <span style="color: #b1b100;">and</span> <span style="color: #0000ff;">@expressions_2</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$head_1</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@expressions_1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$head_2</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@expressions_2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sum_1</span> <span style="color: #339933;">=</span> sum_expression<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$head_1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sum_2</span> <span style="color: #339933;">=</span> sum_expression<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$head_2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$sum_1</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">$sum_2</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@answers</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;$head_1 = $sum_1 = $head_2&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@answers</span><span style="color: #339933;">,</span> find_answers<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#91;</span> <span style="color: #0000ff;">$head_1</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> &nbsp;<span style="color: #009900;">&#91;</span> <span style="color: #0000ff;">@expressions_2</span> <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@answers</span><span style="color: #339933;">,</span> find_answers<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#91;</span> <span style="color: #0000ff;">@expressions_1</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span> <span style="color: #0000ff;">$head_2</span> <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># Effectively only shift the lowest of the heads</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">unshift</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@expressions_2</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$head_2</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$sum_1</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000ff;">$sum_2</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">unshift</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@expressions_1</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$head_1</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$sum_2</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000ff;">$sum_1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066;">return</span> <span style="color: #0000ff;">@answers</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.tty.nl/2009/09/11/perl-quiz-perl-solution-plusified-equations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

