Tuesday, 2017-11-07

New host

For a number of years my friend Thomas has graciously hosted this blog, a shell account, and a number of other things that are essential to the modern person (IMHO). However external circumstances will deprive me of this service, for which I am sorry, for Thomas has been the best sysadmin, and it’s been free!

I’ve shelled out a couple FIAT dollars a month for a “droplet” at Digital Ocean, and worked to transfer stuff from the old server to the new. These are some notes in case I have to do it again.

I chose Ubuntu as a distro because I like the Debian-based packaging.

Web hosting and Perl CGI

I installed Nginx because I’ve vaguely heard it’s “better”. Getting it to deal with CGI scripts in Perl was a bit fiddly but it worked out OK.

You need the fcgiwrap and spawn-fcgi packages.

The following addition was made to the server section of Nginx config for my site.

# we have separate htdocs and cgi-bin dirs under the gerikson.com dir
# this location is to make sure we can have a specific section for cgi-bin
location /cgi-bin/ {
    root /home/www/gerikson.com/;
    try_files $uri =404;
    gzip off;
    fastcgi_pass unix:/var/run/fcgiwrap.socket;
    fastcgi_index index.pl;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Added packages

These are needed for some stuff I host

libcgi-pm-perl
libconfig-simple-perl
libdate-calc-perl
libdatetime-perl
libdbd-sqlite3-perl
libdbi-perl
libjson-perl
libnumber-format-perl
libstatistics-linefit-perl
libtext-csv-perl
libwww-perl
lynx
mutt
sqlite3
zip
perltidy
tree
cpanminus
perl-doc

These are needed for coding contests

libmath-bigint-gmp-perl
libmath-prime-util-gmp-perl

Python 3 stuff

python3
python-pip
virtualenv

Friday, 2017-01-13

493: Under The Rainbow

Project description

Based on the difficulty raiting of this problem I guessed it had an analytical solution, and indeed the answer can be easily expressed in binomial terms.

Thursday, 2017-01-12

214: Totient Chains

Problem description.

Another Math::Prime::Util example.

211: Divisor Square Sum

Problem description.

Another Math::Prime::Util example.

131: Prime cube partnership

Problem description.

Scrounged around in the documentation to Math::Prime::Util and found this under the examples section.

Tuesday, 2017-01-10

105: Special subset sums: testing

Problem description.

The idea to use a bitmask to represent the sets is from this page, as is the clever way to test rule 2.

Thursday, 2017-01-05

Wednesday, 2016-12-28

Project Euler cleanup

Fresh from Advent of Code 2016 I thought it would be nice if I organized my Project Euler solutions and cleaned them up a bit.

They’re being added to my Github repo as I go through them, verify they are working on newer Perls, and generally try to streamline the code.

I’ve found a few “solved” problems that don’t actually have any solutions, but where I do have access to the answer forums. I’ve used solutions there for some problems, and credited the source in the comments.

Thursday, 2016-12-01

Advent of Code 2016

Project website: Advent of Code 2016.

I use Perl for all the solutions.

Most assume the input data is in a file called input.txt in the same directory as the file. Some require extra modules from CPAN.

A note on scoring

I score my problems to mark where I’ve finished a solution myself or given up and looked for hints. A score of 2 means I solved both the daily problems myself, a score of 1 means I looked up a hint for one of the problems, and a zero score means I didn’t solve any of the problems myself.

The times are hours and minutes from the time of the puzzle release (00:00 EST) until I posted an announcement on Twitter.

My goals for this year (in descending order of priority):

  • solve all problems myself (higher cumulative score than last year’s 43/50).
  • solve all problems within 24 hours of release
  • be among the first 1,000 on each day’s leaderboard

Final score

  • Problems solved by myself: 49 / 50 — a big improvement over last year’s 43/50.
  • 3 parts not solved within 24 hours. Shortest time for both parts: 40 minutes. Average time: 5h07m.
  • Average finishing place for each day: 677.8 for part 1, 747.6 for part 2.

Day 1 - Day 2 - Day 3 - Day 4 - Day 5 - Day 6 - Day 7 - Day 8 - Day 9 - Day 10 - Day 11 - Day 12 - Day 13 - Day 14 - Day 15 - Day 16 - Day 17 - Day 18 - Day 19 - Day 20 - Day 21 - Day 22 - Day 23 - Day 24 - Day 25

Day 1 — No Time for a Taxicab

My solution for day 1: part 1, part 2.

I managed to get the correct solution in part 1 despite not taking absolute values in consideration, fixed in code.

Part 2 was frustrating as I didn’t have time to re-think the problem, instead I kludged something on top of part 1.

Score: 2, 9h50m.

Day 2 — Bathroom Security

My solution for day 2: part 1, part 2.

Actually reading the Wikipedia article linked from day 1 helped me with part 2.

Alternate part 2, inspired by this solution.

Score: 2, 4h21m.

Day 3 — Squares With Three Sides

My solution for day 3: part 1, part 2.

The hardest part of this problem was cleaning up the input…

Score: 2, 3h59m.

Day 4 — Security Through Obscurity

My solution for day 4: part 1, part 2.

A fun problem!

Score: 2, 3h38m.

Day 5 — How About a Nice Game of Chess?

My solution for day 5: part 1, part 2.

I already had the required modules installed since 2015 day 4 and initially thought this was going to be straight repeat. While part 1 was indeed simple enough, part 2 threw me for a little loop due to the requirements to keep track of previous entries.

Score: 2, 2h32m.

Day 6 — Signals and Noise

My solution for day 6. Alternative with more map.

Decided to try to solve this over breakfast.

Score: 2, 0h40m.

This was the last of the warmup problems. Things will get tougher from now on.

Day 7 — Internet Protocol Version 7

My solution for day 7: part 1, part 2.

Not very proud of part 2, but at least I know what it does. Using regexps would be the obvious choice but I frankly lack the regex-fu to handle it.

Update: some quick googling revealed the existence of lookahead to deal with overlapping matches, so I whipped together an alternative part 2. This runs appreciably faster (although still within a second).

Just made the first 1,000 submitters for part 2.

Score: 2, 4h36m.

Day 8 — Two-Factor Authentication

My solution for day 8, both parts.

Really didn’t want to do this, it reeked of fiddly bit-flipping, but after thinking a bit the solution presented itself.

Again just squeeked in under the 1,000 first submitters for both parts.

Score: 2, 4h27m.

Day 9 — Explosives in Cyberspace

My solution for day 9: part 1, part 2.

I’m debating whether to award myself 2 points for this, as I had to look for hints for part 2.

The issue was that I was running a recursive solution, but instead of simply counting the characters of a single part and then multiplying by the number of repetitions, I actually created a new array that was the part repeated repetitions times! This led to horrendous execution times.

Score: 2, 5h11m.

Day 10 — Balance Bots

My solution for day 10, both parts.

I usually don’t forget to sort numerically but I did this time, which led to a wild goose chase trying to find out why real input differed from test.

Family commitments prevented a faster time but I still submitted in the first thousand.

Score: 2, 8h15m

Day 11 — Radioisotope Thermoelectric Generators

Finally a solution after almost 6 days.

Not fantastically proud of this, kept plugging away at some solutions even if I’d have had better luck taking a step back and reconsidering. But I solved it myself!

The most problems I had was with the shuffling stuff to and from floors. The last piece fell into place when I realized I had to keep track of the elevator too when considering already visited states.

Solves part 2 in around 11m, which is just barely acceptable.

Score: 2.

Day 12 — Leonardo’s Monorail

Day 12 - complete solution

Score: 2, 5h05m.

Day 13 — A Maze of Twisty Little Cubicles

My solution for day 13: part 1, part 2.

I’ve been thinking a lot about day 11, so the breadth-first search concept came in handy.

Score: 2, 4h39m.

Day 14 — One-Time Pad

My solution for day 14.

This was both tough and kind of boring.

Key insight was this throwaway comment by /u/askalski. Each candidate index is stored in a hash keyed on the duplicate character, and any hit of quintuples is checked

A lot of subtle off-by-one errors made this quite frustrating.

Performance is respectable, especially part 2. Example input:

$ time perl ./d14.pl
==>22728
real    0m0.601s

$ time perl ./d14.pl 2
==>22551
real    0m41.553s

Update 16 Dec 2016 alternative version with cleaner code.

Score: 2, 12h18m.

Day 15 — Timing is Everything

My solution for day 15.

Fast and simple brute-force solved this one.

Score: 2, 1h06m.

Day 16 — Dragon Checksum

My solution for day 16.

The nice and tidy recursive solution I coded for part one takes 1m34s to complete part two, but this is not a very interesting problem so I will just leave it at that.

Score: 2, 3h22m (this is day off for me).

Day 17 — Two Steps Forward

My solution for day 17.

Straight-forward application of techniques known so far. Key to part 2 is to realize BFS returns all solutions, not just the shortest.

Score: 2, submitted after 8h57m on a Saturday.

Day 18 — Like a Rogue

My solution for day 18: complete.

Quick and dirty fourth Advent Sunday breakfast solution. Part 2 runs in 2m30s using the same code as part 1, just many more rows. Brute force baby.

I might try to improve part 2 later.

Edit: here’s a a second attempt. Credit.

Part 2 runtime is 33s for this version.

Score: 2, 3h25m.

Day 19 — An Elephant Named Joseph

My solution for day 19 part 1: part 1.

Part 2 defeated me, this is part 2 with copied code, credit in source.

Update: this alternative is way more Perlish, credit in source!

This is the first problem I actually bailed on, which is a step up from last year. I liked it in a way that you simply couldn’t just run part 2 as a straight continuation of part 1, but had to rethink your strategy, but this problem was too boring for me to bother doing that.

Score: 1, 5h49m.

Day 20 — Firewall Rules

Day 20 - complete solution

Straightforward. Runtime 0.11s.

Score: 2, 4h18m.

Day 21 — Scrambled Letters and Hash

My solution for day 21: part 1, part 2.

A boring and fiddly part 1 led to a straight-forward brute-force solution for part 2. That part finishes in 40s on my machine.

At least I finally got to learn how splice works…

Score: 2, 5h19m

Day 22 — Grid Computing

My solution for day 22: part 1, part 2.

For part 2, I took a chance that there was nothing hindering moving the empty slot in straight lines apart from the “walls”. A simple count of the needed steps gave the solution.

Score: 2, 4h22m.

Day 23 — Safe Cracking

Complete solution.

Entirely unoptimized, runtime for part 2 is 101 minutes!

I was sidetracked by the fact that my first attempt at part 1 gave the correct solution, but failed for part 2.

Score: 2.

Day 24 — Air Duct Spelunking

Complete solution

I used BFS to compute the distances between all points, then used the technique from AoC 2015 day 9 to generate all possible permutations and print them out.

Part 2 runs in less than 2 seconds.

Score: 2, 8h52m on Christmas eve!

Day 25 — Clock Signal

Complete solution

All done! Quick and dirty solution using brute force with crappy pattern detection.

Score: 2, 4h24m.

Advent of Code 2015.

Monday, 2015-12-14

Advent of Code 2015

Project website: Advent of Code.

I started on these puzzles on 7 Dec 2015. So far I’ve completed all of them, all but a few on the same day they were posted.

I use Perl for all the solutions.

Most assume the input data is in a file called input.txt in the same directory as the file. Some require extra modules from CPAN.

A note on scoring

I score my problems to mark where I’ve finished a solution myself or given up and looked for hints. A score of 2 means I solved both the daily problems myself, a score of 1 means I looked up a hint for one of the problems, and a zero score means I didn’t solve any of the problems myself.

Final score: 43 / 50.

All files in one zipped archive.

Days 1 to 4 - Day 5 - Day 6 - Day 7 - Day 8 - Day 9 - Day 10 - Day 11 - Day 12 - Day 13 - Day 14 - Day 15 - Day 16 - Day 17 - Day 18 - Day 19 - Day 20 - Day 21 - Day 22 - Day 23 - Day 24 - Day 25

Days 1 to 4

Day 5 — Doesn’t He Have Intern-Elves For This?

My solution: part 1 - part 2.

I had to get help with part 2 here, found a regexp in the daily solutions thread for this day.

Score: 1.

Day 6 — Probably a Fire Hazard

Part 1 - part 2.

These could definitely be faster, both run in around 30s.

Score: 2.

Day 7 — Some Assembly Required

Had to scrounge around for tips on how to solve this. I had the basic idea down but the problem was keeping track of the solutions as I iterated around.

Score: 0.

Day 7

Day 8 — Matchsticks

Easily the most boring of the problems so far.

Part 2 only.

Score: 2.

Day 9 — All in a Single Night

Essentially the travelling salesman problem but the number of destinations is small enough to brute-force easily. Uses the Algorithm::Combinatorics module. Output is a list of permutations with the total travelling distance prepended, so just use sort -n to find the answer from the output.

Score: 2.

Day 09.

Day 10 — Elves Look, Elves Say

Another computationally expensive problem but even part 2 runs in under 1 minute for me.

Submitted 3h25m after puzzle release.

Score: 2.

Day 10.

Day 11 — Corporate Policy.

So far my favorite problem!

Submitted 5h56m after puzzle release.

Score: 2.

Day 11.

Day 12 — JSAbacusFramework.io.

Another good puzzle. Uses the JSON module.

Both solutions in one file, just comment one line to get part 1.

Submitted 9h25m after puzzle release (I blame family commitments on weekends!).

Score: 2.

Day 12.

Day 13 — Knights of the Dinner Table.

This is a modified day 9 with bidirectionally. Even part 2 which adds another element to the permutation finishes very quickly using brute force.

Submitted 5h03m after puzzle release.

Score: 2.

Day 13.

Day 14 — Reindeer Olympics.

A troll! The immediate brute force approach is to simply advance time 1s at a time and check the “position” of each deer at that time. But this is “obviously” dumb so I used a quicker approach for part 1. Part 2 made me regret it…

Submitted for 2 stars 4h04m after puzzle release.

Part 1, part 2.

Score: 2.

Day 15 — Science for Hungry People.

A combination of outside factors and frustration at getting my indexes right made this a tedious slog.

Submitted for 2 stars 9h45m after puzzle release.

Score: 2.

Day 15.

Day 16 — Aunt Sue.

A fun one. Submitted for 2 stars after 2h37m.

Score: 2.

Day 16 part 2.

Day 17 — No Such Thing as Too Much

Tried a recursive approach first, but got stuck for the part 2 and looked in the daily thread for inspiration. Figured out how to use combinations by looking at other’s code.

Submitted for 2 stars after 6h18m.

Score: 1.

Day 17.

Day 18 — Like a GIF For Your Yard

Conway’s Game of Life! I’ve never coded this before so it was a fun exercise.

I tried using arrayrefs first but got tripped up by the deep copy (dclone in the code) and decided to go for a hash of hashes instead. I think this contributes to the slow execution time of ~15s.

Submitted for 2 stars after 6h00m.

Score: 2.

Day 18.

Day 19 (Saturday) — Medicine for Rudolph

A tough one! I solved part 1 no problems but had to hunt around for hints for part 2.

Day 19 part 1.

Score: 1.

Day 20 (Sunday) — Infinite Elves and Infinite Houses

Lack of time and impatience led me to look for hints for this. I had the right initial idea but thought looking for divisors of an integer without the PARI package would be too slow, and I have yet to find a way to install that on the machine I’m using.

In the end it didn’t matter but I wanted this done.

Full credits in source.

Day 20.

Score: 0.

Day 21 — RPG Simulator 20XX

I went for a straightforward solution of generating all combos of items and then running a simulated battle with each.

Day 21.

Score: 2.

Day 22 — Wizard Simulator 20XX

Not a very good solution, relies on brute force to simulate all possible spell casts and then prints out a win or loss. Note that I had to run it for 5M iterations to get the answer to part 2. This is the only problem I didn’t finish in the same day as it was released (apart from the 7 first ones).

Day 22.

Score: 2.

Day 23 — Opening the Turing Lock

Straightforward apart from the slightly ambigious jio instruction — read carefully what it means.

Day 23.

Score: 2.

Day 24 (Christmas eve) — It Hangs in the Balance

I tried to finesse the answer by hand first but it didn’t simply work to manually adjust the packages to get desired answer. Instead I checked valid combinations, but with the following assumptions/optimizations:

  1. I sorted the packages in descending order to check those combinations first.
  2. I assumed the answer wouldn’t contain more than 6 elements, so just checked combinations up to that value of k.
  3. I didn’t bother to confirm the remaining packages would sum correctly.

Runs in about 2s.

Day 24.

Score: 2.

Day 25 (Christmas day) — Let It Snow

Straightforward iterative solution. Runs in over half a minute, those with CS backgrounds used modular exponentiation and got much faster results.

Day 25.

Score: 2.

(un)License

The solution files are in the Public Domain.

Tuesday, 2015-11-17

315: Digital root clocks

Problem description.

This was a fiddly one. But once you get the actual state changes correct it’s simply a matter of extracting the values that will be displayed and calculate how much it’ll “cost” to display them.

Saturday, 2015-11-14

387: Harshad numbers

Problem description.

Another one off the list of unsolved problems in ascending difficulty. Perl string manipulation makes this one easy.

Wednesday, 2015-09-09

357: Prime generating integers

Problem description.

I had to try to solve this without access to my previous favorite Perl module: Math::Pari, and it took almost an hour to run.

Thursday, 2014-01-30

Poetry

John Gruber:

File Edit View Special

When I see those four words, they evoke not a thought but a feeling. Poetry, in the form of a menu bar.

I mention this in chat, and literally seconds later @varjag writes

< varjagg> roses are red
< varjagg> violets are blue
< varjagg> you are my special
< varjagg> as file edit view

Saturday, 2012-11-17

90: Cube digit pairs

An unexpected way of using two cubes to make a square.

The key to this is to handle the fact that 6 and 9 are equivalent. Once I’d handled that I had to eliminate duplicates. Otherwise it’s pretty straightforward.

Tuesday, 2012-10-16

188: Tetration

The hyperexponentiation of a number.

You get to the start of the trail by reading the Wikipedia article on tetration.

Monday, 2012-10-15

110: Diophantine reciprocals II

Find an efficient algorithm to analyse the number of solutions of the equation 1/x + 1/y = 1/n.

We know from problem 108 how the answer is formed. The trick is to generate a number of integers from the prime factors, to find which combination has the most divisors.

Thursday, 2012-10-11

148: Exploring Pascal’s triangle

Problem link.

This was a fun one, I did try a 2nd-order brute force approach after some research and realized it would break the 1-minute rule but let it run anyway for about 10 minutes and got the answer.

Wednesday, 2012-10-03

204: Generalised Hamming Numbers

Problem description.

Did quite some research on this but in the end extended a “classic” Hamming number generator (for 5-smooth numbers) that I found on Rosettacode.com. Bit of a cheat and runs in 2 minutes instead of the required 1.

Tuesday, 2012-10-02

121: Disc game prize fund

Investigate the game of chance involving coloured discs.

I suck at probabilities and had to google for hints for this one.

Monday, 2012-10-01

144: Investigating multiple reflections of a laser beam

Investigating multiple reflections of a laser beam.

This was fun, once I figured out the geometry. Another thing to watch out for is comparing 2 floats for equality.

Thursday, 2012-09-13

93: Arithmetic expressions

Using four distinct digits and the rules of arithmetic, find the longest sequence of target numbers.

Straightforward brute force, helped by the Perl Algorithm::Combinatorics module to find different permutations and so on.

Runs in about 36s with some debugging info.

Wednesday, 2012-09-12

174: Counting hollow square laminae

Counting the number of “hollow” square laminae that can form one, two, three, … distinct arrangements.

This was basically the same as 173, my code needed changes to 3 lines and some hash counting code.

Tuesday, 2012-09-11

101: Optimum polynomial

Investigate the optimum polynomial function to model the first k terms of a given sequence.

o/~ All by myself…

Pretty proud of this one. Used linear algebra to solve for the coefficients in each successive polynomial. Unfortunately the Perl Math::Matrix package didn’t let me easily extract the values so I had to copy-paste into a separate script to check against the correct values.

173: Hollow Square Laminae

Using up to one million tiles how many different “hollow” square laminae can be formed?

On a roll today!

This wasn’t too hard once I sorted out all the fencepost errors.

94: Almost equilateral triangles

Investigating almost equilateral triangles with integral sides and area.

The hinge for this is discovering that the solution can be expressed as a Pell’s equation, this puzzle is helpful.

Monday, 2012-09-10

88: Product-sum numbers

Fell for the spoiler urge, not proud of it.

Friday, 2012-09-07

84: Monopoly odds

In the game, Monopoly, find the three most popular squares when using two 4-sided dice.

This marks my return(?) to Eulering. I did a lot of research for this a long time ago, and was planning on implementing a Markov chain approach based on the results from this page but after falling for the trap of googling for solutions I found that most people simply simulate the dice rolls, counting the number of times the dice hits each cell.

I simulated 1 million throws and got a result in about 5 seconds.

Thursday, 2011-11-03

193: Squarefree numbers

Problem description.

Found searching for “project euler” in OEIS.

Saturday, 2011-10-29

Friday, 2011-10-28

187: Semiprimes

Problem description.

Easily done if you have a few million primes on hand.

There’s a sequence in Sloane that gives the answer directly, too!

Thursday, 2011-10-27

100: Arranged probability

Finding the number of blue discs for which there is 50% chance of taking two blue.

I started researching the hypergeometric distribution and thought about comparing it to a binomial distribution at large numbers before twigging that if you expand the problem it’s a quadratic Diophantine equation. There’s an online solver that provides factors for these equations and after that it was simply a matter of plugging them in.

Wednesday, 2011-10-26

203: Squarefree Binomial Coefficients

Problem description.

I had in mind optimisations in only calculating half the triangle, but in the end it didn’t signify. I used the Pari issquarefree() function.

Biggest issue was forgetting telling Perl to use arbitrary precision integers.

119: Digit power sum

Investigating the numbers which are equal to sum of their digits raised to some power.

I turned this over in my mind trying to find some limit so I didn’t have such an enormous search space. Then I found A023106 in Sloane which gives all but the last few terms, and then it was really fast to brute force.

To be quite honest this was a bit easy for this level.

Thursday, 2011-01-27

Monday, 2011-01-03

Keeping a FreeBSD system up to date

I like using FreeBSD compared to Linux (or “lulnix” as we cool kids say nowadays) but distros like RedHat and Ubuntu have the edge when it comes to making it easy to keep your system up to date with the latest patches.

You’d think there was a simple one-shot way of doing this, but so far I’ve settled for the following method. It’s documented here as much for my own memory as anything else.

  1. refresh your ports tree with cvsup: cvsup -g -L 2 /usr/local/etc/ports-supfile (you should edit the ports-supfile to reflect your geographical location).
  2. run the portupgrade command: portupgrade -a -PP -Rr -i.

The options I use for portupgrade are:

  • -a: all ports
  • -PP: use only packages (use a single P if you want to compile a port where a package isn’t available)
  • -Rr: both recursive and upwardly recursive
  • -i, for interactive. I run this because once when I ran without it my perl got upgraded to a new point release under me and broke my CPAN modules. YMMV.

Monday, 2010-11-29

On calculators

One of the sons in the house is in the last year of high school and as math is not his favorite subject he’s only now raised his need of a graphing calculator. I did a perfunctory research of the market and purchased a generic Texas Instruments model for around €70.

One thing that struck me is that today’s calculators aren’t that much different than the ones I remember when I was a first-year college student, lo so many years ago. We’re still looking at a plethora of multiply-labeled buttons, grayscale screens, and extremely limited memory. In an age where a basic calculator is practically disposable, memory is cheap and handheld UI innovation rampant thanks to cellphones and computers, it’s a bit weird to see a tech area looking so stable.

Part of the reason is of course that if you’re dealing with students, you don’t want them to be too connected or have too much computing at their disposal during exams. But that just raises another questions. Barring global catastrophe (in which case basic math skills would be nice to have, but knowledge of agriculture even more desirable) any pupil attending higher education will have a calculator within reach for the rest of their lives.

So, basic arithmetic has been automated, and in fact, even quite complicated algebra has been too, thanks to tools like Mathematica and Maple. In fact, as long as you have access to the web Wolfram Alpha will solve most equations faster than you can type them in.

Is it time to face the fact that doing arithmetic with pen and paper is like making pots on a pottery wheel? It’s a nice craft, probably will be quite popular for a small part of the population, but it’s essentially not needed in a modern society?

Please note I’m not saying mathematics is obsolete. It’s probably more important than ever. But I do think we need to find a better way of teaching it than just mechanically learning rules like long division and decomposition of factors. Leave the drudgery of math to the computers, and try to move on to teach the actual use of math in real life.

Friday, 2010-11-12

The obligatory iPhone post

So I have an iPhone now, as have 60% of Stockholm’s inhabitants. It’s no longer a very interesting thing to say.

I moved to the iPhone from the Nokia E61, which I still think is a really good phone for its time. Here’s some random thoughts on the differences.

The iPhone excels at music playing and gaming. I’m not that big a fan of differnt social networking apps, but the web browser is miles better. Basic stuff like alarms work better. SMS rocks.

I miss having a physical keyboard though, but this is something I think I’ll get used to in time.

What the E61 was better at was multitasking, and IRC and Twitter apps. I used WirelessIRC and Gravity both by Jan-Ole Suhr, and they rocked. I use Rooms for IRC and Echofon for Twitter, and neither app has the ease of access and navigation that WirelessIRC and Gravity has.

However, it should be noted that these were the only apps I purchased for the E61. Purchasing software is so much better and easier on the iPhone it’s not even possible to compare.

Another thing I miss is the ability to “remote control” the phone from the computer. While Nokia PC Suite and its successor Ovi are a horrible conglomeration of ugly little apps, at least they made it easy to browse content and most especially read and write text messages from the desktop. I can’t really complain about iTunes syncing but I do wish there was something for Messages on the desktop.

Monday, 2010-09-06

Some thoughts on Google Wave

When Google announced Wave the hype was immense, it was like everyone took Gmail and squared it and thought it would be that awesome! And basically that’s what the Wave developers thought too. Well I can’t remember what I did but I got an invite and hopped on, and right away realised that there was no-one there. The invite-only start (for performance reasons) limited the appeal and usefulness of Wave.

Because I think it was pretty useful, at least once they got the early kinks worked out. Me and some far-flung mates used it to plan some trips together, and Wave was pretty useful for that. It would have been better with a mobile interface but it was decent.

The thing is, Wave wasn’t the next coming of Gmail, it was the next coming of Microsoft Outlook. Outlook is merely the front-end to Exchange, which does all the boring and useful bits (routing email, planning calendars etc). And sure, it works, but not very well. At my current place of work we have Office Communicator Server (OCS) which is basically MS Live Messenger in a corporate suit. The nice thing about OCS is that it integrates into Exchange, so you can see whether a coworker is online, or in a meeting or whatever.

However, sometimes you want to start from the task, not the person. That’s where Wave began - you had a project, or a trip, or just a task involving some people. It could start with just you and then expand, like a lot of tasks do. However, instead of snowballing into a long mail thread, you actually had the option of keeping Waves clean and on topic.

Wave was flawed - it was before its time, it tried to solve problems that don’t often turn up in the wider world of the web, but which do turn up lots of times within organizations. Maybe Microsoft will learn from Wave and build better collaboration tools than Exchange.

Friday, 2010-04-09

Fear of an iPad planet

[Warning, this post contains profanity.]

There’s a lot of blogther[1] around these here tubes about the closed nature of the Apple iPad. Exhibits: Doctorow and Danny O’Brien.

Basically the the thesis is that if this closed platform takes over, all creativity is stifled by unaccountable gatekeepers and humanity is doomed.

That’s bollocks. Here’s why.

Primo. The iPad is a toy for rich people. Period. Only a tiny minority will buy it, and only a minority of that minority will use it as their only way to access the internet. For fuck’s sake, you need a computer (PC or Mac) to sideload content to it[2]. There’s zero chance that this will become the only fucking way to access the internet, because Apple doesn’t sell to everyone on the planet. They sell to people who can afford Apple products. So far, they’ve made a lot of money doing this, while companies like Lenovo and HP are struggling. Why should they change?

Secundo. Closed platforms are the fucking greatest for some things, like gaming. I happen to think that the console systems are better for gaming than the PC platform. And if you disagree with me on this, you’re per definition in the minority. Seriously, check out the sales figures. Money talks. And if we’re gonna get serious about tackling spyware and malware and shit, we should mandate that 99% of internet users only get to use a closed, locked down, Trusted Computing-verified internet appliance. The general-purpose PC is like a fucking chainsaw in these people’s hands.

Tertio. If you happen to raise a geek or feel a pressing need to make him or her learn to code fucking Haskell, there are literally MILLIONS of used PC’s that can run your choice of Lulnix, and he/she can spend their precious time coding blog platforms when they should be out in the sun, getting D vitamins.

Quarto. Who died and made Apple god? If the iPad succeeds in taking over the world, they’ll end up like IBM or Microsoft. This is not the end of computing history.

In closing, shut the fuck up already, you apocalyptic freetards.

Update 2010-04-14: the tone of this post has been inspired by the Angry Mac Bastards podcast, who go forth and rip Doctorow and Winer to shreds regarding their iPad views in episode 55. Listen to them for even more sound and fury, signifying nothing much!


[1] a portmanteau of “blog” and “blather”, and yes, I realise if you have to explain it’s not very good. Go invent your own term.

[2] Conveniently. I guess you can buy stuff OTA too. Do I look like I do research?

Thursday, 2010-03-25

Notes on Project Euler

Project Euler “is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve.” In other words, you need to get down and program to solve the problem[1].

I’ve recently reached Level 3 (solved over 100 problems) and thought I’d share some notes on what I’ve learned.

PE programming is “pure” programming, as in you’re working with algorithms and not systems. There’s rarely anything more complicated than file access needed. In fact, I’d say you need an aptitude for problem solving rather than programming, and the skills needed to solve PE problems are probably not really translatable to real work out in the real world, where you’re dealing with real people and real hardware and networks. To be sure, nowhere on PE do they say that this is programming in the wider sense, as opposed to Computer Science, but you’d be surprised how many CS grads think it does (I’m mocking you, Haskell nerds!).

The typical PE problem looks amenable to brute force, but it pays to research before jumping in. Wikipedia and Mathworld are great resources for a lot of the problems, often explaining the math behind them and sometimes having the algorithms you need.

Spoilers. I find it pretty hard to concentrate on a problem and not want to know the solution, especially when I’m into “grind” mode and just want to level up (this happens a lot with me and puzzle games too). There are plenty of spoilers around for the early problems (the ones that most people manage to solve) but as you move up they get sparser and sparser, and are usually in languages other than your chosen one. Often it’s enough for me to just get a hint. After you’ve solved a problem, you get access to a forum where others discuss their solutions. This can be an eye opener, but there’s no need to share your crappy solution if you don’t want to.

I use Perl. I thought of using PE to learn another language (Python), but finally I felt it was more fun to explore something I’m pretty proficient in than to learn something else. Perl has all the things you need for these problems (so far), especially as there are tons of libraries for specific applications. One of the more useful is Math::Pari, an interface to the Pari suite of numerical algorithms.

Perl is really nice for stuff like string manipulation and set operations. It’s also really easy to build ad-hoc data structures, although the syntax grows hairy really fast.

Python seems very popular among PE participants. Another popular language among the people who bother to post to answer threads is J), and of course Haskell has some vocal devotees.

I find it challenging and fun to work on these problems, and I encourage you to do the same!

[1] although there are some wizards who manage with pencil and paper, at least for the earlier problems.

Tuesday, 2009-04-07

Setting foreground and background colours in iTerm

Update 2011-09-03: I’ve just gotten my hands on an iMac running Lion, and Terminal.app now has built-in support for different colour schemes. This blog entry has a nice one.

iTerm white-on-black

The Mac has strangely few terminal emulators, unless you set up X and invoke the Deep Ones in other ways. So far, I’ve found iTerm to be the best one.

You cannot set iTerm to use black background and white text, but you can trick this with AppleScript. Put the following into your .bash_profile or similar:

setColor() {
  osascript -e "tell application \"iTerm\"
    set current_terminal to (current terminal)
    tell current_terminal
      set current_session to (current session)
      tell current_session
      set background color to \"black\"
      set cursor color to \"white\"
      set foreground color to \"white\"
    end tell
  end tell
end tell"
}
## now invoke the function, and clear the screen 
setColor
clear

When you start a new window, the background will be white but it will soon become white on black, as ghod intended.

Thanks Jedrek for helping me with this!

Thursday, 2009-04-02

Deleting an Outlook message via a filter

If you try to set the option “delete it” from the Outlook Rules and Alerts wizard, you’ll get a message that that particular rule is “client-side only”, which means that Outlook has to be running for the rule to work.

If you’re trying to set up rules for mobile use, for example, this is less than ideal.

One workaround is to choose “move to a folder”, and move to the folder “Deleted Items”. This achieves basically the same thing, with the added bonus of keeping the message for review if needed.

Monday, 2009-01-05

Ignoring idiots on IRC

Sure, IRC has the /ignore command, but it just removes all mention of a nick from a channel. Sometimes this is what you want, but Mike recently shared a little irssi script that will simply censor anything an idiot says. That way the conversation isn’t as disjointed as it could be otherwise.

I’ve modified the script so that more than one nick can be censored. My version is here. Basic knowledge of Perl is required to use this. It’s also easy to evade by changing nicknames, I’ll try to fix this in later versions.

To install in irssi, follow these instructions.

Monday, 2008-04-14

Dell Gold support — awesome. Their followup survey? Much less so

I recently had a spot of bother with my work lappy. The screen went all blurry after a short while of use. I didn’t mind this as it didn’t happen when the laptop was docked.

However I felt it needed to be fixed, so I called the Dell Gold support line in Sweden. Very professional service from them, a tech arrived the day after with a replacement motherboard and LCD screen. So far, so happy.

This morning I arrive to find an email from Dell asking me to participate in a survey about my experience. I’ve ignored these in the past, only to be spammed by reminders, and I thought that in this case I should take it as a I was very happy with the service I got.

So like a fool I click the link to some god-awful outsourced company (prognostics.com). A series of barely literate, badly sequenced survey questions pop up. Each takes about a minute to load. They are repetitive. They have no discernable order. They seem to reiterate the same damn point over and over again.

So I waste about 10 minutes of my time with this crap and feel obscurely that I’m more unhappy with the level of service I’ve received than before. This is the last time I’m answering these, I’ll be creating a filter to bin them from now on.

Saturday, 2008-01-12

Getting native 1400x1050 resolution with Xorg i810 drivers on a Dell Latitude D505

I’ve been using Ubuntu 7.10 on a Latitude D505 for a while now, and I’ve always been disappointed with the screen resolution. The max I could get was 1280x1024, while the native resolution is 1400x1050.

I recently had to reconfigure X on this machine (dpkg-reconfigure xserver-xorg) and chose the intel driver (recommended by the configure script). However, it turns out that this driver hangs the machine when you close the lid. The older driver i810 works in this regard, but the max resolution is too low.

The solution is to use the 915resolution application. This does some weird hacking of the video BIOS to allow Linux to use the full resolution.

Using it in Ubuntu is a breeze. Simply install the .deb package and reboot.

Thursday, 2007-11-01

Somewhere in the heavens… they are waiting

Instant nostalgia. Thanks to the Aleph One project and these instructions I was able to compile the Aleph One application on my Ubuntu lappy and play Marathon 2.

It’s a lot of fun, especially as I can point out “we had that in Marathon 13 years ago” while playing Halo 3 with Leo. This pisses him off no end.

Friday, 2007-09-28

Is it Friday?

The site isitfriday.net provided an essential service: answering the question “is it Friday today?”.

Apparently it wasn’t deemed essential enough, cause the service no longer exists.

David has stepped up to the breach with http://isitfriday.gnapp.org/. Here’s my contribution:

#!/usr/bin/perl -w
use strict;
use CGI qw(:standard);
my $wday = (gmtime( time ))[6];
my $msg = 'no';
if ( $wday == 5 ) {
    $msg = b( 'YES!' );
}
print header;
print start_html( 'Is it Friday?' );
print h1({-style=>"text-align: center"}, $msg );
print hr;

You can see it in action here.

N.B. this script is not tested for days other than Friday. Also, your timezone will have to be in the general vicinity of UTC for it to work for you.

Thursday, 2007-05-24

Scripts in Nautilus

I found out today that if you’ve installed a script in Nautilus, you won’t see it in the contextual menu until you’ve visited the script directory in Nautilus.

Install a script in ~/.gnome2/nautilus-scripts/ and making it executable.

Then visit that directory in Nautilus to “enable” it.

I’m not sure if you have to do this for every script you install, or only for the first one.

Sunday, 2007-05-13

For the love of $DEITY, check the return of system in Perl!

So there we were at work, wondering why part 2 of our home-brewed customer survey system[1] wasn’t sending the mails it should be sending.

Turns out that the perl script responsible read from one table in the database to find out the recipients of the emails. It then generated a form of authentication, updated the database to say that the mails had been sent, then called

system( "/usr/local/bin/email.pl" );

where email.pl was another script written by the same developer.

Note the lack of return value from that call to system.

So what happened was that in the distant mists of time (about 2 months ago) we switched source control systems. Apparently we lost our executable bits on some scripts, because email.pl was readonly and owned by Apache.

Had we checked the return value, we would at least have had a warning that something was wrong. But now the system apparently “worked” for a month or so, and we only realised that nothing was being sent when the responses dried up.

I’ve re-written the code to check if the call to email.pl was succesful, and only if it was would the database be updated.

Now we have to re-send all emails older than a month, which will probably put our server on a spam blacklist. Sigh.

Lesson: code defensively.

[1] Why we haven’t got a third-party solution for this is hard to understand, unless you worked there 2 years ago, when development time was considered free and maintainance was never factored in the cost equation.

Tuesday, 2007-04-03

[SvSe] 24-timmarsmyndigheten?

Screenshot from 24h.myndigheten.se

Monday, 2007-04-02

Variables in (s)printf formats

Here’s a fun thing I learned for the first time today: you can have variables in formats for printf or sprintf.

Here’s a contrived example:

#!/usr/bin/perl -w
use strict;

sub variable_format {
    my ( $in, $len ) = @_;
    printf( "%0${len}d\n", $in );
}

variable_format( 42, 3 );  # prints 042
variable_format( 42, 9 );  # prints 000000042

Interestingly, I can’t find any mention of this in Perl’s documentation for sprintf.

Tip of the hat to Linus.

Sunday, 2007-03-25

Twitter posting script in Perl

Here’s a stab at a script for posting to Twitter:

#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
use XML::Simple;
use URI::Escape;

my $username = 'your_twitter_username';
my $password = 'your_twitter_password';

my $message = shift or die "usage: $0 message\n";

if ( length $message >= 140 ) {
    $message = substr( $message, 0, 139 ); 
    warn "truncating message to: $message\n";
}
$message = uri_escape( $message );

my $ua = LWP::UserAgent->new();
# tell Twitter who we are
$ua->agent( "$0/0.1 " . $ua->agent );

my $req = HTTP::Request->new( POST =>
                  'http://twitter.com/statuses/update.xml');
$req->content_type( 'application/x-www-form-urlencoded' );
$req->authorization_basic( $username, $password );
$req->content( "status=$message" );

my $res = $ua->request( $req );

my $xml;
if ( $res->is_success ) {
    $xml = XMLin( $res->content );
} else {
    print "Posting failed " . $res->status_line . "\n";
}

my ( $created, $name, $screen_name, $id ) =
  ( $xml->{created_at},
    $xml->{user}->{name},
    $xml->{user}->{screen_name},
    $xml->{id} );

print << "EOF";
Your message

  $message

was succesfully posted at $created 
as user $name ($screen_name) with ID $id.
EOF

Thanks to Jim for the inspiration.

By the way, I’m gerikson at Twitter.

Update 2007-03-27: I removed the wget version as I don’t maintain it any more.

This Twitter API wiki is pretty helpful.

Sunday, 2007-01-28

FizzBuzz

Nearly flubbed this. Time constraints suck.

First implementation, aka bog-standard:

#!/usr/bin/perl -w
use strict;
my $i = 1;
while ( $i < 101 ) {
    if ( $i % 3 == 0 and $i % 5 == 0 ) {
    print "FizzBuzz\n";
    } elsif ( $i % 3 == 0 ) { 
    print "Fizz\n";
    } elsif ( $i % 5 == 0 ) {
    print "Buzz\n";
    } else {
    print "$i\n";
    }
    $i++
}

Maybe I’ll play a bit with this later… the online comments have degenerated into golfing in people’s favourite languages.

Check here for a funny-cause-it’s-true “example” in Java, everyone’s favourite enterprise language… (first comment).

Tuesday, 2006-08-15

Mounting LVM volumes from a USB disk

Quick start

  • attach the disk to the computer
  • Run the following commands as root or via sudo:

(The first command finds LVM volumes. The second one activates them.)

root@host:~# vgscan  
  Reading all physical volumes.  This may take a while...  
  Found volume group "foo" using metadata type lvm2  
root@host:~# vgchange -a y foo  
  2 logical volume(s) in volume group "foo" now active  
root@host:~# ls /dev/foo  
  root swap_1  
root@host:~# mount /dev/foo/root /mnt

Background

This may help others, I had a hell of a time getting it working, but that was just because I didn’t understand the concepts at all.

Background: a Linux laptop lost its video card recently. I was able to back up the most important files via FireWire to another machine before I couldn’t see the screen, but I felt I should have the entire hard drive handy in case I miss anything. So I removed the hard drive from the laptop and put it in a $40 USB enclosure.

An aside: this resulted in a very nice little wallet with 40G of storage, but with one big disadvantage. It gets its power entirely from the USB port, but unless you have powered port (generally one at the back of a tower PC) you need an external power brick. Most laptops cannot run the drive from their ports. Lugging a power brick around kinda negates the portability of the device. The point was moot in my case, as there was no power brick included in the package.

(In addition, el cheapo USB hubs can’t power this sucker either. I had a 3.5” enclosure with 3 USB ports that could, however.)

So, I plugged the drive to a laptop also running Linux (Ubuntu, same as the last one). The drive automounted and I could see the /boot partition. Obviously that’s formatted in some generic fashion that the automounter can recognise. A scan of /var/log/messages gave the device as /dev/sdb.

root@inspiron8600:~# fdisk /dev/sdb

The number of cylinders for this disk is set to 4864.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
  (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): p

Disk /dev/sdb: 40.0 GB, 40007761920 bytes
255 heads, 63 sectors/track, 4864 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

  Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *           1          31      248976   83  Linux
/dev/sdb2              32        4864    38821072+   5  Extended
/dev/sdb5              32        4864    38821041   8e  Linux LVM

(note that I’m root here, no mucking around with sudo when there’s a lot of commands to issue!)

OK, so the data is on /dev/sdb5, in a LVM volume. What the heck is that? Linus has this to say:

You don’t want to use LVM, it’s a source of confusion and headache. It’s a toy variant of VxFS but doesn’t work nearly as well.

Words to live by, but Ubuntu has helpfully stashed my data into an LVM volume and I needed to get it back.

The short answer is to run vgscan:

root@inspiron8600:~# vgscan
 Reading all physical volumes.  This may take a while...
 Found volume group "Ubuntu" using metadata type lvm2

OK, this is where I went off the rails. You see, I thought that the volume group “Ubuntu” was the one on the host hard drive. So I spent a lot of time googling for solutions (someone somewhere must have had this experience before!), reading about using Windows (ugh!) and how not to do stuff. Then I read what I should have from the the beginning, the LVM HOWTO.

In the section Common tasks it tells you about Creating a volume group. This could then be mounted.

Aha! I tried

# vgcreate usb_volume /dev/sdb5

but got the message that it was already a part of a volume group, namely “Ubuntu”!

Mounting /dev/Ubuntu to /mnt was a moments work. I was able to copy the needed data easily.

(Update: /dev/Ubuntu showed up because I ran vgchange before, not knowing what that command did.)

Caveat: In the course of writing this, I tried to recreate the steps I used. However, I got this message back:

root@inspiron8600:~# vgscan
  Reading all physical volumes.  This may take a while...
  /dev/Ubuntu/root: read failed after 0 of 4096 at 38168100864:
    Input/output error
  /dev/Ubuntu/root: read failed after 0 of 4096 at 0: Input/output error
  /dev/Ubuntu/swap_1: read failed after 0 of 4096 at 1581187072:
    Input/output error
  /dev/Ubuntu/swap_1: read failed after 0 of 4096 at 0: Input/output error
  Found volume group "Ubuntu" using metadata type lvm2

I couldn’t mount the partitions either.

Looks like I was in the nick of time!

I have no clue whether the act of mounting the LVM volume via USB ruined it, or if this was just a bad disk. Be careful!

Thanks to Stefan and Linus for helping me with this!

Saturday, 2006-05-20

Networking between Linux and Windows with FireWire (IEEE1394)

I wanted a quicker way to transfer files between two laptops than via wifi. One’s is running Ubuntu Linux, the other Windows XP.

Both machines have a 4-pin FireWire port (labeled 1394, apparently someone owns the rights to the “FireWire” name and someone else doesn’t want to pay royalties). I borrowed a 4-pin to 4-pin cable from my brother-in-law and set out to try to connect the machines.

I knew that Windows has built-in IP-over-1394 support, the clincher was enabling it under Linux. Ubuntu has the required modules installed and the kernel I use can use them. There is a project page for Linux1394 if you need to get the modules and install them by hand.

I loaded the network module eth1394 by running

$ sudo modprobe eth1394

(Maybe this isn’t strictly necessary, but I didn’t find any reference to the module in the dmesg output.) Checking /var/log/messages, I saw that the interface got the name eth2.

Then I connected the computers with the cable (after enabling the interface in Windows). I heard a “cable connected” sound in Windows. Running

C:\> ipconfig /all

showed me that the interface was up. After a while I got a private address (169.254.203.16, netmask 255.255.0.0). I configured a static address on the Linux side:

$ sudo ifconfig eth2 up 169.254.203.17 netmask 255.255.0.0

I then started an FTP client in Windows, pointed it to the address defined in Linux, and started transferring files. I’m getting about 2.5 MB/s which isn’t too shabby.

Update: some quick perusal of the transfer logs gave me a average transfer rate of 1.45 MB/s.

Friday, 2006-03-10

Outputting dates in RFC822 and ISO8601 formats in Perl

Correctly formatted date strings are needed for RSS generation, among other things RSS. Diego shows how to do this in Java. This is my version in Perl

 #!/usr/bin/perl -w

 use strict;
 use POSIX qw(strftime);

 my $now = time();

 # We need to munge the timezone indicator to add a colon between the hour and minute part
 my $tz = strftime("%z", localtime($now));
 $tz =~ s/(\d{2})(\d{2})/$1:$2/;

 # ISO8601
 print strftime("%Y-%m-%dT%H:%M:%S", localtime($now)) . $tz . "\n";
 # RFC822 (actually RFC2822, as the year has 4 digits)
 print strftime("%a, %d %b %Y %H:%M:%S %z", localtime($now)) . "\n";

The output is

 2005-01-05T01:35:08+01:00
 Wed, 05 Jan 2005 01:35:08 +0100

There are some small issues I haven’t found clarification for at this late hour of writing. The first is whether the day should be zero-padded in the RFC822 case. As it is now it’s space-padded. Accordng to RFC822, the day is zero-padded.

The second is how to handle locale settings — RFC822 specifies that the weekdays and months be in the US locale. I’m pretty sure that you need extra magic in Perl for this not to work, but I’ll take a look at that tomorrow.

Yet another reason to standardize on ISO8601, I guess.

Update 2006-03-10: Eli Billauer was kind enough to mention this error to me, kudos to him.

Monday, 2006-02-20

Formatting FAT32 under Windows XP

Apparently you can’t format volumes larger than 32GB in FAT32 under WinXP. Anything larger will have to use NTFS. I’ve got a largish drive in a USB-connected enclosure that I’d like to use under Linux, so NTFS was out. As far as I know, the Linux support for it is still experimental.

Well, as the good book says, Google, and ye shall find. The first suggestions from MS was to boot into Win98/ME and use their FORMAT command to do this. This is akin to performing brain surgery with a butter knife dipped in pus.

But I also found Jens-Uwe Mager’s Windows port of the Linux command mkdosfs that worked like a charm.

So now I’m backing up the MP3’s on this machine. Can life get much better?

Tuesday, 2006-01-31

Converting from ISO-8859-1 to UTF-8 in Perl

When posting my observations via email any Swedish characters are converted to quoted-printable ISO-8859-1 by Gmail. However, this blog is in UTF-8. This is how I translated the input from the mail message.

#!/usr/bin/perl -w
use strict;
use MIME::QuotedPrint qw( decode_qp );
use Encode qw( decode encode );

# split the mail message
my ( $headers, $body );
{
    local $/ = undef;
    ( $headers, $body ) = split( "\n\n", <STDIN>, 2 );
}

# decode the qouted-printable input
$body = decode_qp( $body );
# decode to Perl's internal format
$body = decode( 'iso-8859-1', $body );
# encode to UTF-8
$body = encode( 'utf-8', $body );

print $body, "\n";

The result is piped into a second script that formats the actual posting.

Pretty basic, eh? But until you know how, it can be a bit frustrating getting this to work.

Friday, 2005-12-30

Perl tools for mp3s

I recently had to edit a bunch of mp3s. I found the following Perl modules helpful.

  • mp3cut. Contains a script mp3cat that concatenates mp3 files. Very simple to use.
  • MP3::Tag. For all your mp3 tagging needs. Contains a script mp3info2 that can read and update tags.

These modules work fine under Cygwin running in Windows.

Wednesday, 2005-12-28

iTunes “skip shuffle” and “remember playback” settings

I grabbed a bunch of audio books in mp3 format but was shocked, shocked I say! when the files weren’t bookmarkable (i.e. they didn’t remember where I stopped listening) and worse, the files were included in the shuffle. When you have 1,388 files, each a minute long, that kinda sucks.

I pecked around in iTunes a bit and saw that there was a setting in the Info->Options panel for a track that included the checkmarks

  • Remember playback position
  • Skip when shuffling

Perfectomento! BUT… you can only set these options one file at a time. Damn you Apple! Damn you to hell!!

(If you don’t use AppleScript. Which I don’t. Because I don’t have a Mac.)

I found 2 links on Google which offer some alternatives. The reason for this post is essentially that del.icio.us is down ATM and I need somewhere to post these:

Update 2005-12-29: basically there are two ways of handling this.

  • Convert to AAC format and rename

I tried this variant, but the resulting files were much larger than the files in mp3 format. I guess you can get around this by playing with the converting options, but I suspect they only apply to importing from CDs (see the second link above).

  • Merge the mp3 files and set the appropriate settings manually.

I went with this variant. A quick search of CPAN resulted in a bunch of utilities I could use. I merged the tiny files into chapters, then added what ID3v2 tags I could. The rest were added in iTunes, along with the required playback and shuffle options.

I will try to find out more about ID3v2 tag handling later, so as to automate this even more.

Saturday, 2005-11-12

Ubuntu rocks!

Due to a little accident, my wife’s standard laptop is hors de combat — basically, I dropped our son on it (from a small height, I hasten to add) and the power connection broke. So it boots, for about 5 seconds, before discovering that the battery is flatter than Kansas.

I have in my possession an elderly laptop with no more than 256M of RAM, much too little to run a modern Microsoft OS. So I decided to check Ubuntu out. This is supposed to be “Linux for human beings”, so I figured this would be OK for non-geeks.

I downloaded an install CD via BitTorrent and used it to install it. The installation went really well. I had to fight my old-skool Debian and OpenBSD instincts and just let things go as designed. Ubuntu has made a great product — it installed seamlessly on the lappy and presented a clean, workable graphical interface that I think will be acceptable for Linux-o-phobes.

The only thing that didn’t work out of the box was the wi-fi pc-card I bought expressedly for its OpenBSD compatibility. However, I discovered that I had no less than four wi-fi cards lying around, and the oldest 3Com card worked fine.

I’ve been using this laptop all day (in between re-stacking our woodpile) and I really enjoy it. Small stuff, like Alt-Tab window-switching and Alt-F4 window close work exactly like in Windows. But having a real Debian system underneath just feels sooo much better than Windows crap leavened with Cygwin goodness.

Wednesday, 2005-09-14

The good old days

Matthew: Generation VIC20.

Chris: So Dad, what’s a computer science class for at school?
Me: Well, you learn to program there for example.
Chris: Program?
Me: Yes, to write computer programs using a special language.
Chris: You mean like games?
Me: Well, yes I suppose.
Chris: Like Star Wars Knights of the Old Republic?
Me: Umm, no.

Classic.

I guess you could learn a lot by copying source code, even if it was just BASIC spaghetti code. With line numbers.

Tuesday, 2005-08-30

Date in another timezone

Cool hack in Unix: if you know the zonefile abbreviation for a timezone, you can use it to get the date there:

$ TZ=PST8PDT date
Tue Aug 30 05:07:39 PDT 2005

This also works:

$ TZ=America/Los_Angeles date
Tue Aug 30 05:08:17 PDT 2005

Timezone files are in /usr/share/zoneinfo on OpenBSD and Linux.

Monday, 2005-08-22

Screen quickstart

This is quick basic intro to GNU Screen.

If you haven’t installed screen, do so. It rocks.

Starting up

Start screen. You’ll get a splash screen. Hit space to make it go away.

Depending on your flavour of *nix, you’ll get between 1 and n screens. First one is numbered 0. Try to switch to screen 1: Ctrl-a 1. If you get a message, create screen 1 with Ctrl-a c (create). Now you can switch back and forth between 0 and 1 with Ctrl-a 0 and Ctrl-a 1.

Want a “real” Ctrl-a? (If you’re in Emacs, you do.) Type Ctrl-a a.

Detaching

Start an editor in one screen, load a file and start editing. Detach with Ctrl-a d (detach). Logout of the shell, then login again. Attach to the screen: screen -r (reattach). You should be back where you left. Continue editing.

Finally

Screen is perfect for flaky connections, you’ll be back where you left off even if you get a hangup.

You can use screen -r -d to cleanly reattach from another session.

If you want a bunch of screens at startup, edit your ~/.screenrc. Mine looks like this:

shell -$SHELL
screen -t SHELL0  0
screen -t ROOT    1
screen -t SHELL2  2
screen -t SHELL3  3
screen -t SHELL4  4
screen -t SHELL5  5

The first line starts the current $SHELL in login mode. The others set up six windows and gives them titles.

Type man screen for more info.

Happy screening!

Update: here’s a more full-featured tutorial. (Via NTK.)

Wednesday, 2005-08-17

Django CRUD

Matt has written a nice tutorial on how to use Django in a simple CRUD situation: Django Generic Views: CRUD.

(CRUD, by the way, stands for Create, Read, Update, Delete — basic database manipulation. The title of this post is in no way a reflection on Django on my part.)

Matt and others are very excited over Django — it’s Ruby on Rails for Python. I’ve been meaning to learn Python for a long time, but lately I’ve felt I’m too old a dog for new tricks. More on this in a later post, maybe.

Tuesday, 2005-03-08

OpenBSD wi-fi hardware

This list is here so that I can check out hardware in stores via the phone.

  • ADMtek ADM8211 based CardBus/PCI adapters (atw) (G)
  • Aironet Communications 4500/4800 ISA PnP, PCMCIA and PCI 802.11b adapters (an)
    • Aironet 4500/4800
    • Cisco 340/350
  • Atheros AR521x based CardBus 802.11a/b/g adapters (ath), including: (G)
    • 3Com 3CRPAG175
    • Aztech WL830PC
    • D-Link DWL-A650
    • D-Link DWL-AB650
    • D-Link DWL-AG650
    • D-Link DWL-G650B
    • Elecom LD-WL54AG
    • Elecom LD-WL54
    • Fujitsu E5454
    • Fujitsu FMV-JW481
    • Fujitsu E5454
    • I/O Data WN-AB
    • I/O Data WN-AG
    • I/O Data WN-A54
    • Linksys WPC51AB
    • Linksys WPC55AG
    • NEC PA-WL/54AG
    • Netgear WAB501
    • Netgear WAG511
    • Netgear WG511T
    • Orinoco 8480
    • Orinoco 8470WD
    • Proxim Skyline 4030
    • Samsung SWL-5200N
    • SMC SMC2735W
    • Sony PCWA-C700
    • Sony PCWA-C300S
    • Sony PCWA-C500
  • Atheros AR521x based PCI 802.11a/b/g adapters (ath), including: (G)
    • D-Link DWL-A520
    • D-Link DWL-AG520
    • D-Link DWL-G520
    • HP NC4000
    • Linksys WMP55AG
    • Netgear WAG311
    • Netgear WG311
    • Proxim Skyline 4032
    • Senao NL-5354MP
  • Atmel AT76C50x based USB 802.11b adapters (atu), including: (G)
    • Acer Peripherals AWL300
    • Acer Peripherals AWL400
    • Aincomm AWU2000B
    • Bluetake BW002
    • D-Link DWL-120
    • Geowave GW-US11S
    • Linksys WUSB11
    • Linksys WUSB11-V28
    • Netgear MA101 rev B
    • OQO model 01 builtin wireless
    • Ovislink AirLive WL-1120USB
    • OvisLink AirLive WL-1130USB
    • SMC 2662W-AR
    • SMC 2662W-V4
  • Intel PRO/Wireless 2100 802.11b adapters (ipw) (G)
  • Intel PRO/Wireless 2200BG/2225BG/2915ABG 802.11a/b/g adapters (iwi) (G)
  • Intersil PRISM-2-3 based 802.11b Compact Flash adapters (will be detected as PCMCIA adapters) (wi)
    • Buffalo AirStation
    • D-Link DCF-660W
    • ELSA XI800
    • Linksys WCF12
    • Netgear MA701
  • Intersil PRISM 2-3, Lucent Hermes and Symbol Spectrum 24 based PCMCIA 802.11b adapters (wi), including:
    • 3Com AirConnect 3CRWE737A
    • ACTIONTEC HWC01170
    • Addtron AWP-100
    • Agere Orinoco
    • ARtem Onair
    • BUFFALO AirStation
    • Cabletron RoamAbout
    • Compaq Agency NC5004
    • Contec FLEXLAN/FX-DS110-PCC
    • Corega PCC-11
    • Corega PCCA-11
    • Corega PCCB-11
    • Corega CGWLPCIA11
    • Dlink DWL650 revisions A1-J3
    • ELSA XI300
    • ELSA XI325
    • ELSA XI325H
    • EMTAC A2424i
    • Ericsson Wireless LAN CARD C11
    • Gemtek WL-311
    • Hawking Technology WE110P
    • I-O DATA WN-B11/PCM
    • Intel PRO/Wireless 2011
    • Intersil Prism II
    • Linksys Instant Wireless WPC11
    • Linksys Instant Wireless WPC11 2.5
    • Linksys Instant Wireless WPC11 3.0
    • Lucent WaveLAN
    • NANOSPEED ROOT-RZ2000
    • NEC CMZ-RT-WP
    • Netgear MA401
    • Netgear MA401RA
    • Nokia C020 Wireless LAN
    • Nokia C110/C111 Wireless LAN
    • NTT-ME 11Mbps Wireless LAN
    • Planex GW-NS11H Wireless LAN
    • Proxim Harmony
    • Proxim RangeLAN-DS
    • Samsung MagicLAN SWL-2000N
    • SMC 2632 EZ Connect
    • Symbol Spectrum24
    • TDK LAK-CD011WL
    • US Robotics 2410
    • US Robotics 2445
  • Intersil PRISM 2-3 and Symbol Spectrum24 based PCI 802.11b adapters (wi), including:
    • 3Com AirConnect 3CRWE777A PCI
    • Belkin F5D6000 PCI (a rebadged WL11000P)
    • Corega CGWLPCIA11 PCI
    • Eumitcom WL11000P PCI
    • Dlink DWL520 PCI revisions A and B
    • Global Sun Technology GL24110P PCI (untested)
    • Global Sun Technology GL24110P02 PCI
    • Intersil Mini-PCI
    • LinkSys WDT11 PCI (a rebadged GL24110P02)
    • NDC/Sohoware NCP130 PCI
    • Netgear MA301 PCI
    • Netgear MA311 PCI
    • US Robotics 2415 PCI (rebadged WL11000P)
    • Nortel E-mobility 211818-A
    • Symbol LA4123
  • Intersil PRISM 2.5/3 based USB 802.11b adapters (wi), including:
    • Acer Warplink USB-400
    • Actiontec HWU01170
    • AirVast WM168b
    • Ambit WLAN
    • Apacer Wireless Steno MB112
    • ASUS WL-140
    • Compaq W100
    • Corega WLUSB-11
    • Corega WLUSB-11 Key
    • D-Link DWL-120 (rev F)
    • D-Link DWL-122
    • I-O DATA WN-B11/USB
    • Intel PRO/Wireless 2011B
    • Intersil Prism 2X
    • JVC MP-XP7250
    • Linksys WUSB11 v3.0
    • Linksys WUSB12
    • Melco WLI-USB-KB11
    • Melco WLI-USB-KS11G
    • Melco WLI-USB-S11
    • Microsoft MN510
    • Netgear MA111 (version 1 only)
    • Pheenet WL-503IA
    • Planex GW-US11H
    • Siemens SpeedStream SS1022
    • Sitecom WL-022
    • Syntax USB-400
    • US Robotics 1120
    • Z-Com XI-725/726
    • Z-Com XI-735
    • ZyXEL ZyAIR B-200
  • Ralink RT2500 based CardBus 802.11b/g adapters (ral), including: (G)
    • MSI CB54G2
    • Surecom EP-9428-g
  • Ralink RT2500 based PCI 802.11b/g adapters (ral), including: (G)
    • ASUS WL-130g
    • Minitar MN54GPC-R
  • Raytheon Raylink and Aviator 2.4/PRO PCMCIA 802.11 FH adapters (ray)
  • Realtek RTL8180L based CardBus 802.11b adapters (rtw), including: (G)
    • Corega CG-WLCB11V3
    • Netgear MA521

(G): Drivers for hardware marked with (G) are only included in the GENERIC kernels, but are not included on the various distribution floppies (including the cd-rom boot image).

(Source: OpenBSD i386 hardware list.)

Saturday, 2005-02-05

Gnus and Microsoft Outlook

For a long time I have been having trouble sending mail to people using Microsoft’s mail clients Outlook and Outlook Express. I use Gnus, an all-singing, all-dancing news-mail-and-everything reader for use in Emacs.

The trouble was that if I included any 8-bit characters in the header of the message, Outlook would translate any 8-bit characters in the body of the message to an equal sign and two hex characters. This was intensely irritating, as I naturally assume that all free software is superior to commercial offerings, especially Microsofts.

The trouble is that the version of Gnus I’m using (v5.8.7) doesn’t encode the headers in quoted-printable, thus confusing Outlook no end.

The solutions is to place the following in your .emacs or .gnus file:

;; iso-8859-1 support for headers
(require 'gnus-msg)
(add-to-list 'gnus-group-posting-charset-alist
     '(message-this-is-mail 'iso-8859-1 (iso-8859-1)))

Thanks to Kai Großjohann for this info.

Keywords: Gnus, gnus newsreader, GNU/Emacs, Emacs, Xemacs, MIME, mime, quoted-printable, transfer-encoding, Microsoft Outlook, Outlook Express, mangled, 8-bit characters.

Note: this was originally posted on another server, I’m posting it here in an effort to clean up my online life.

Wednesday, 2005-01-12

Combining PDF files

Need to combine two or more PDF files into one under Unix? Use the following command:

  gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=merged.pdf \
  source1.pdf source2.pdf source3.pdf etc.pdf

Obviously, you’ll need Ghostscript for this to work.

(From macosxhints)

Tuesday, 2004-10-05

No Piker

For some reason (probably because I feel an itch to hack) I was thinking about Plan 9 today. So it seemed an omen that /. had a call for questions for Rob Pike, co-creator of Unix and Plan 9.

I read some of the links in the article, and this pessimistic view left me thinking. Pike’s point is that (academic) software research no longer matters. We’re in a sterile wasteland of Windows, Linux, and the Web. No new ideas are being explored.

Well, that’s fine as far as it goes, but a meme that’s brewing is the coming dominance of mobile devices and content — quite different from desktop or server computing.

These points from the article show some possible fields for research:

Only one GUI has ever been seriously tried, and its best ideas date from the 1970s. (In some ways, it’s been getting worse; today the screen is covered with confusing little pictures.) Surely there are other possibilities. (Linux’s interface isn’t even as good as Windows!)

Ties in nicely with this post.

There has been much talk about component architectures but only one true success: Unix pipes. It should be possible to build interactive and distributed applications from piece parts.

Again relevant in the mobile space.

The future is distributed computation, but the language community has done very little to address that possibility.

Who knows? Mobiles are getting more and more powerful. GPS, encryption need processing.

The Web has dominated how systems present and use information: the model is forced interaction; the user must go get it. Let’s go back to having the data come to the user instead.

Also very relevant from a user perspective. Data must come to you, when and where you want it, with a minimum of fuss.

Will academia pick up the thrown gauntlet? Lets hope someone does.

Monday, 2004-10-04

Teaching kids to code

Matthew asks how one goes about to teach kids to code. Viking is too small yet, but it’s an interesting question. I know Hanna is quite proficient in HTML, mostly by copying and pasting, but Leo has shown no interest whatsoever in coding.

Part of the problem is the polished and complex nature of todays computers. In our day, you could slavishly copy pages of code and get something that worked. Even if it was just copying, you got down and dirty with the code. Some of it stuck. A curious kid (which I was not) could explore further, learning more and more. Whether learning Basic and VIC-20 assembler was a good thing is another question…

But now? Who can feel that they can produce something like Doom 3 by themselves?

Having said that, I believe a programming environment should have a graphic component. A former co-worker’s son loves (loved? it’s been a while) a DOS-based program for scripting dungeon adventures. A language of that kind could introduce the building blocks of programming — loops, conditionals, events — in a fun way that gives instant feedback and makes debugging fun.

An OO component could make it easy to “clone” your succesful monster, trap, whatever, and re-use the code. Introducing test cases is perhaps overkill at this stage…

I haven’t seen Lego’s Mindstorm stuff, but if anyone can make IDEs for kids, it should be them.

Update: Bill Ward writes in a comment:

For me it was BASIC on the Commodore too. But today’s kids have options as well. I think Javascript may be a good choice. My wife is taking a Flash class at the local college, and teaching me what she is learning. That could be a good choice too, except for the fact that it’s rather expensive.

I remember someone prophesying that Windows Scripting would be the next “laymans programming language”, but I haven’t seen MS promoting it that way. Having an easy to learn powerful scripting language built into the OS would introduce lots of people to programming, not just kids.

Wednesday, 2004-05-26

why I know perl

I learned Perl in my first real consulting gig at Agero. A large business directory company in Sweden wanted to synchronise their print catalogue with the Web. Additionally, they wanted an interface for customers to create their own ads on the Web. This was the sexy part of the project. I wasn’t involved there.

The synchronisation didn’t work yet, so every Monday my colleague had to take a 650 MB XML-file and feed it to a Java program that inserted the contents into a big old Oracle database running on a Sun Starfire. She was much more billable than I was, so as I incautiously admitted to Un*x knowledge I was asked if I could take over this job.

The XML was full of errors, unescaped ampersands, invalid characters… The Java program choked if it couldn’t parse the file, so you had to manually search for the error and fix it, then try again. A successful run took about 9 hours.

I started by chopping up the file into the component entries and checking for bad stuff. This is trivial, just set $/ to whatever end element suits your fancy, but it took some reading of the Perl Cookbook before I had it nailed.

Then I started looking at how to automate this stuff. I eventually wrote a sophisticated run-control program that could be started with at, and that sent email when something went wrong.

Just when I had cut down the effective load time from three days to about 11 hours, the whole project got axed. I later learned that this was the third attempt to integrate the print version with an online database.

The contractor more or less blamed the whole debacle on us, even though it could be fairly laid at bad project management and unrealistic promises from the client to its customers. Oh well.

In the middle of my next project, I was cding up from a directory over a slow ssh link and accidentally rmd all my perl code. When I called the admins of the machine they helpfully informed me that as the machine wasn’t in production it didn’t have backups.

So now I know more Perl than I really want to. But I’m still learning more every day.

Wednesday, 2004-04-14

ordering email

After a tip from Rui, I’ve started to sort my work mail (mail addressed to me personally, and the support box) into quarterly archives.

Long experience has told me never to throw away mail, and the quarter seems to be a good time period in which to ask yourself “when did I get that mail?”

Wednesday, 2004-03-24

HTML typography

Learn about the fifteen spaces defined in Unicode at this page.