Wishful Coding

Didn't you ever wish your
computer understood you?

Hosted IRC for Teams

It has started. A few weeks ago I was just playing around with Pallet, now I have been on Hacker News and have a couple of users.

My workflow is pretty desktop oriented, so when I was required to use a web application to keep in touch with teammates and Hacker School friends, I thought I could make a perfectly fine group communication tool based on IRC with plenty of desktop clients available.

The idea is pretty simple: Give every team a VPS with an IRC server, but the devil is in the details. A vanilla IRC server is a bit awkward as a collaboration tool. You might as well telnet to each other directly.

An important piece to the puzzle is ZNC. ZNC is a powerful bouncer with a ton of plugins. It stays connected to the server on your behalf 24/7, replaying all the messages you missed while disconnected. So that is user accounts and persistent chat right there.

Another important part is Hubot. Hubot is an IRC bot that can execute commands and notify you about things like Git commits, build failures and more.

There is also a web interface, because… you know, some people do live on the web.

Finally, I have some grand plans for file sharing, but that is for another time.

The result speaks for itself, check it out: teamrelaychat.nl

I realise this is not for everyone, but if you’re anything like me, chances are it fits your workflow better than these web based services.

clojure.core.logic magic square

Last night my brother told me about this puzzle where you have a square of 3x3 that you have to fill with 1-9 in a way that all columns and rows sum up to 15.(this is not a real magic square, but anyway)

After discussig our strategies for a bit, we went on to think about generalising the problem to bigger squares.

The next morning we tested our theory in excel and produced a 4x4 square. The method we used was to fill in numbers at random, then switching them around horizontally until all collumns equalled 34 and finally switching them around vertically to make the rows work out.

Once we started thinking about doing the 5x5 grid, I suggested I might do it faster using core.logic. I was wrong.

user=> (time (test/magic 3))
(1 5 9)
(6 7 2)
(8 3 4)
"Elapsed time: 451.880413 msecs"
nil
user=> (time (test/magic 4))
(1 2 15 16)
(7 8 9 10)
(12 11 6 5)
(14 13 4 3)
"Elapsed time: 6386.272944 msecs"
nil
user=> (time (test/magic 5))
OutOfMemoryError GC overhead limit exceeded

The code simply generates N2 logic variables in the 1-9 domain that are distinct. These are then sliced up in rows and collumns and constrained to sum up to the “magic number”.

(ns test
  (:refer-clojure :exclude [==])
  (:use clojure.core.logic
        clojure.pprint)
  (:require [clojure.core.logic.fd :as fd]))

(defn grid [n] (repeatedly (* n n) lvar))

(def rows partition)

(defn cols [n grid] (apply map list (rows n grid)))

(defn sum [ls res]
  (conde
    ((== ls []) (== res 0))
    ((== ls [res]))
    ((fresh [h t inter]
       (conso h t ls)
       (fd/+ h inter res)
       (sum t inter)))))

(defn magic [n]
  (let [g (grid n)
        nums (range 1 (inc (* n n)))
        ndom (apply fd/domain nums)
        lsum (/ (apply + nums) n)
        lines (concat (rows n g) (cols n g))]
    (->> (run 1 [q]
           (everyg #(fd/dom % ndom) g)
           (fd/distinct g)
           (everyg #(sum % lsum) lines)
           (== q g))
      first
      (rows n)
      (map println)
      dorun)))

I suspect I can still beat my brother to 6x6 by implementing one of the techniques outlined on wikipedia in a good old imperative style, especially since he’s not even trying.

graph

VMfest Base Image

I’m playing with Pallet to setup an IRC server and bouncer. Pallet uses vmfest to deploy to VirtualBox.

While vmfest comes with some prepared images, I found that my laptop would not run them, so I made my own, with a lot of help from Antoni Batchelli.

  • Create an image in VirtualBox with a NAT and host-only network.
  • Install your favourite distro.
  • Install an SSH server.
  • Setup passwordless sudo
  • Make sure /etc/network/interfaces contains both eth0 and eth1.

      auto eth0
      iface eth0 inet dhcp
      auto eth1
      iface eth1 inet dhcp
    
  • Update and upgrade all packages.
  • Install the guest additions
  • On some Debian based distros, remove persistent-net.rules.

This should give you a working machine, but we’re not done yet. You still need to make the hard disk multi-attachable.

If you where to use this image in Pallet, you could only use it once. Multiattach means that every time a machine is made, a new copy-on-write image is created so the original stays intact.

To do this, delete the VM, but not the vdi file, and run the following command:

VBoxManage modifyhd the/disk.vdi --type multiattach

Finally, you need to create a meta file with the same name as the disk image, but with the .meta extension. As an example:

 {:os-type-id "Ubuntu_64",
  :sudo-password "vmfest",
  :no-sudo false,
  :username "vmfest",
  :os-family :ubuntu,
  :os-version "12.04",
  :os-64-bit true,
  :password "vmfest",
  :description "Ubuntu 12.04 (64bit)"
  :packager :apt}
Published on