Monday, October 22, 2007

OLPC FTW

We'll start with a classic:

Two men are standing beside the road watching the new backhoe dig a hole. "Look at that. Think of how many men with shovels could be working if we didn't have that thing," says the first man. The second one says, "Hey, think of how many men with spoons could be working if we didn't have the shovels!"


Take the following with a grain of salt, as I'm no Steven D. Levitt, nor a Malcolm Gladwell, and certainly not any Thomas L. Friedman.

I think that the One Laptop Per Child program, an initiative to get easy-to-use, open source personal computers to children around the world, has the potential to completely change the world's economy for the better. As little economists, we're all taught somehow or another that:

  • Tools have throughout human history multiplied our ability to accomplish tasks. Technological change is responsible for the majority of our economic advancement over our ancestors.
  • The most advanced tools to date (that don't fly around in space or kill people) are computers, which create and distribute massive amounts of information worldwide, and allow people to create and organize that information in useful ways to increase productivity.
  • Specialization of Labor makes the members of a cooperative market more effective at creating wealth than the same number of people operating on their own.
  • A free labor market dictates the cost of labor in proportion to the need for that type of labor. Specialized skilled labor tends to be a non-commodity, and wages are higher for those working in specialized fields. This is why income and education are directly correlated.


See where I'm going with this? Become a software developer. Just kidding; you can already do that if you want to, or you may have already. (If so, congratulations.) The important thing is that we get more software developers, more graphic artists and writers and musicians and paper pushers and bean counters. Let's let everyone have a computer to write instructions for and pay the ones who can do it in a useful capacity.

Labels:

Eight Queens in SQL

I told my co-workers last week that SQL could help one figure out, among other puzzles, Eight Queens. I'm sure they believed me, but I couldn't find it on the internets so I wrote it. Here it is, just run it on your database of choice:


--SQL Eight Queens

--Create the board:
CREATE TABLE rows (
id integer PRIMARY KEY);
INSERT INTO rows (id) VALUES (1),(2),(3),(4),(5),(6),(7),(8);

CREATE TABLE cols (
id integer PRIMARY KEY);
INSERT INTO cols (id) VALUES (1),(2),(3),(4),(5),(6),(7),(8);

--Get a set of queens:
SELECT
cols.id AS col1, rows.id AS row1,
col2, row2,
col3, row3,
col4, row4,
col5, row5,
col6, row6,
col7, row7,
col8, row8
FROM rows, cols, (SELECT
col3, row3,
col4, row4,
col5, row5,
col6, row6,
col7, row7,
col8, row8,
rows.id AS row2, cols.id AS col2
FROM rows, cols, (SELECT
col4, row4,
col5, row5,
col6, row6,
col7, row7,
col8, row8,
rows.id AS row3, cols.id AS col3
FROM rows, cols, (SELECT
col5, row5,
col6, row6,
col7, row7,
col8, row8,
rows.id AS row4, cols.id AS col4
FROM rows, cols, (SELECT
col6, row6,
col7, row7,
col8, row8,
rows.id AS row5, cols.id AS col5
FROM rows, cols, (SELECT
col7, row7,
col8, row8,
rows.id AS row6, cols.id AS col6
FROM rows, cols, (SELECT
col8, row8,
rows.id AS row7, cols.id AS col7
FROM rows, cols, (SELECT
rows.id AS row8, cols.id AS col8
FROM rows, cols)
AS b8
WHERE cols.id != col8 AND rows.id != row8 --This checks rook moves
AND (cols.id + rows.id != col8 + row8) --This checks bishop moves
AND (cols.id - rows.id != col8 - row8)
) AS b7
WHERE cols.id != col8 AND rows.id != row8
AND cols.id != col7 AND rows.id != row7
AND (cols.id + rows.id != col8 + row8) AND (cols.id - rows.id != col8 - row8)
AND (cols.id + rows.id != col7 + row7) AND (cols.id - rows.id != col7 - row7)
) AS b6
WHERE cols.id != col8 AND rows.id != row8
AND cols.id != col7 AND rows.id != row7
AND cols.id != col6 AND rows.id != row6
AND (cols.id + rows.id != col8 + row8) AND (cols.id - rows.id != col8 - row8)
AND (cols.id + rows.id != col7 + row7) AND (cols.id - rows.id != col7 - row7)
AND (cols.id + rows.id != col6 + row6) AND (cols.id - rows.id != col6 - row6)
) AS b5
WHERE cols.id != col8 AND rows.id != row8
AND cols.id != col7 AND rows.id != row7
AND cols.id != col6 AND rows.id != row6
AND cols.id != col5 AND rows.id != row5
AND (cols.id + rows.id != col8 + row8) AND (cols.id - rows.id != col8 - row8)
AND (cols.id + rows.id != col7 + row7) AND (cols.id - rows.id != col7 - row7)
AND (cols.id + rows.id != col6 + row6) AND (cols.id - rows.id != col6 - row6)
AND (cols.id + rows.id != col5 + row5) AND (cols.id - rows.id != col5 - row5)
) AS b4
WHERE cols.id != col8 AND rows.id != row8
AND cols.id != col7 AND rows.id != row7
AND cols.id != col6 AND rows.id != row6
AND cols.id != col5 AND rows.id != row5
AND cols.id != col4 AND rows.id != row4
AND (cols.id + rows.id != col8 + row8) AND (cols.id - rows.id != col8 - row8)
AND (cols.id + rows.id != col7 + row7) AND (cols.id - rows.id != col7 - row7)
AND (cols.id + rows.id != col6 + row6) AND (cols.id - rows.id != col6 - row6)
AND (cols.id + rows.id != col5 + row5) AND (cols.id - rows.id != col5 - row5)
AND (cols.id + rows.id != col4 + row4) AND (cols.id - rows.id != col4 - row4)
) AS b3
WHERE cols.id != col8 AND rows.id != row8
AND cols.id != col7 AND rows.id != row7
AND cols.id != col6 AND rows.id != row6
AND cols.id != col5 AND rows.id != row5
AND cols.id != col4 AND rows.id != row4
AND cols.id != col3 AND rows.id != row3
AND (cols.id + rows.id != col8 + row8) AND (cols.id - rows.id != col8 - row8)
AND (cols.id + rows.id != col7 + row7) AND (cols.id - rows.id != col7 - row7)
AND (cols.id + rows.id != col6 + row6) AND (cols.id - rows.id != col6 - row6)
AND (cols.id + rows.id != col5 + row5) AND (cols.id - rows.id != col5 - row5)
AND (cols.id + rows.id != col4 + row4) AND (cols.id - rows.id != col4 - row4)
AND (cols.id + rows.id != col3 + row3) AND (cols.id - rows.id != col3 - row3)
) AS b2
WHERE cols.id != col8 AND rows.id != row8
AND cols.id != col7 AND rows.id != row7
AND cols.id != col6 AND rows.id != row6
AND cols.id != col5 AND rows.id != row5
AND cols.id != col4 AND rows.id != row4
AND cols.id != col3 AND rows.id != row3
AND cols.id != col2 AND rows.id != row2
AND (cols.id + rows.id != col8 + row8) AND (cols.id - rows.id != col8 - row8)
AND (cols.id + rows.id != col7 + row7) AND (cols.id - rows.id != col7 - row7)
AND (cols.id + rows.id != col6 + row6) AND (cols.id - rows.id != col6 - row6)
AND (cols.id + rows.id != col5 + row5) AND (cols.id - rows.id != col5 - row5)
AND (cols.id + rows.id != col4 + row4) AND (cols.id - rows.id != col4 - row4)
AND (cols.id + rows.id != col3 + row3) AND (cols.id - rows.id != col3 - row3)
AND (cols.id + rows.id != col2 + row2) AND (cols.id - rows.id != col2 - row2)
LIMIT 1337; --Arbitrary, you can let yours go all day.
--Note that this won't return very many unique solutions (unless your queens have numbers written on them)


I realize that this could be more elegant by trimming out the hard-coded values, and that I could set it up for N queens, but I got excited when it ran for 8. I wrote a nonrecursive brute-force version that ended as expected, with me sighing and restarting Postgres. If I go and edit it, it'll certainly be to put the results in a human-readable form. Because it's really cool, but isn't smart enough to choose good placements ahead of time, I give myself 7 Queens out of a possible 8:



Labels: ,