samedi 21 juin 2008

Solving a small puzzle in Python

A colleague went to San Francisco for WWWDC08, and brought back a nice puzzle as a omiyage.
The big letters announcing a very hard puzzle were too tempting. Here is the idea :

You get 36 tiles. Each of the tile contains 4 different symbols, one on each of its corner. The number of possible symbols is 7. You need to arrange those tiles in a 6x6 square so that each all corners.



#!/usr/bin/python
from copy import deepcopy

corners = [(0,0),(1,0),(1,1),(0,1)]

def compute_grid(N):
return [ (i,j) for i in range(N) for j in range(N) ]

def add(u,v):
(ux,uy) = u
(vx,vy) = v
return (ux+vx, uy+vy)

def turn(piece,rot):
rot = (rot%4 + 4) % 4
return piece[rot:] + piece[:rot]

def compute_snail(N):
res = []
dirs = [ (0,-1),(1,0),(0,1),(-1,0), ]
d,cur = 0, ((N-1)/2, (N-1)/2)
for i in range(N*N):
res.append(cur)
tryturn = add(cur, dirs[(d+1)%4])
if tryturn not in res:
d,cur = (d+1)%4, tryturn
else:
d,cur = d, add(cur, dirs[d])
return res

def game(N, pieces, path):
board = compute_grid(N)

def solver(board, remaining, path):
def put(el,pos):
def compatible(c):
val, pt = c
return (pt not in board) or (board[pt] == val)
def put(couples):
new_board = deepcopy(board)
for (val,pt) in couples:
new_board[pt] = val
return new_board
couples = [ (el[i], add(pos,corners[i])) for i in range(4)]
if all(map(compatible,couples)):
return put(couples)
else:
return None

if remaining == []:
return [board]
else:
res = []
cur, new_path = path[0], path[1:]
candidates = [(piece,rot) for piece in remaining for
rot in range(4)]
for (piece,rot) in candidates:
el = turn(piece,rot)
new_board = put(el,cur)
if new_board is not None:
new_rem = deepcopy(remaining)
new_rem.remove(piece)
res += solver(new_board, new_rem, new_path)
return res
return solver({}, pieces, path)


from random import randrange
from random import shuffle

def create_game(N=6,K=7):
d = {}
for pos in compute_grid(N+1):
d[pos] = randrange(K)
elements = map(lambda pos: [ d[add(pos, v)] for v in corners],
compute_grid(N))
elements = map(lambda t: turn(t,randrange(4)), elements)
shuffle(elements)
return elements


N=5
print game(N,create_game(N,N+1), compute_grid(N))

mardi 20 mai 2008

Google Treasure Hunt STEP2

Google released a second test to their Treasure Hunt.
They give a zip file with a bunch of file and your task is to
compute the sum of the numbers given at the kth line of all the file with some pattern in the path and some extension, then do it a second time and give back the product
of the result.

I don't really so the interest of the whole thing, and especially the last task :
do it again once and compute the product.

Anyway here is my best shot on it :

find is pretty handy to get all the file matching some kind of pattern. You can then batch a command on them using exec.

find -path *stu* -name *.pdf -exec something

To get the 5th line, I will consider it as the last out of the five first lines.
find -path *stu* -name *.pdf -exec head -n 5 | tail -n 1 \;

Uh oh... exec doesn't like pipes. Whe can still have bash interpret that correctly :
find -path *stu* -name *.pdf -exec bash -c 'head -n 5 {} | tail -n 1 ' \;

Looks good... Let's pipe it to awk to get the result.
find -path *stu* -name *.pdf -exec bash -c 'head -n 5 | tail -n 1 ' \; | awk '{a+=$1}END{print a}'

Uh oh... The result is still incorrect. The test says that if the file is less than 5 lines long, you should consider it null. Let's fix it quick and dirty : first create a file with five empty lines, and then I ran :

find -path *stu* -name *.pdf -exec bash -c 'cat {} prefix | head -n 5 | tail -n 1 ' \; | awk '{a+=$1}END{print a}'

DONE!

lundi 12 mai 2008

J'ai découvert récemment jyunkudô (ジュンク堂) , jusqu'ici la plus grande librairie que j'ai pu voir à Tokyo. Le rayonnage des livres pour apprendre le japonais est très bien fourni. On y trouve même des grammaires écrites en français : si vous êtes un habitué de kinokuniya (紀伊国屋) je vous conseille vraiment d'aller y faire un tour.

J'y ai acheté entre autres Read Real Japanese (voir photo ci-dessus), un bouquin d'étude de textes. J'avoue n'en être qu'au premier texte, mais le concept est super. Le livre est par ailleurs livré avec un CD Audio sur lequel une japonaise lit les textes avec un accent un peu ancien (g est joliement nasalisé).

samedi 10 mai 2008

Le monde bizarre du Fûzoku (風俗)


La semaine dernière, alors que je me baladais près de Kabuki Cho, j'ai dépassé un type qui distribuait des tracts mystérieux la tête bien basse. Au moment de le croiser, j'ai identifié ceux-ci comme des exemplaires gratuits d'un magazine de manga en cours de lancement. Je reviens donc sur mes pas pour en récupérer un exemplaire...

Et là surprise! il ne s'agit pas d'un magazine de mangas, mais d'un journal d'annonces d'emploi spécialisé dans la prostitution légère. Rien de vraiment sulfureux, le petit journal vise vraiment à embaucher des jeunes filles en mal d'argent, leur proposant des boulots pas très ragoûtant pour un salaire attractif (de l'ordre de 35000 yens soit 220 euros par jours).

C'est cet industrie que l'on appelle le fûzoku (風俗). Il paraitrait qu'elle prenne un gros pourcent du PIB du Japon. Pas étonnant que le petit bouquin fasse tranquillement ses trois cents pages.

La publicité ci-dessous laisse même sous entendre qu'un petit boulot de ce type (en l'occurence, très soft, accompagner les clients pour des rendez vous galants), sont un bon moyen de rencontrer l'homme idéal.

Il s'agit en effet de se vanter de tout et n'importe quoi pour effacer la gêne qui pourrait freiner les candidates potentielles. Un job de conversation coquine sur internet propose de "rentrer dans le secteur de l'IT". Un job de "service" à domicile est illustré par la photo d'une femme en imperméable beige, très "Office Lady".

Pour chaque service un joli pléonasme... Parfois pas simple à saisir du tout:
telephone lady (テレホンレディー), sauna individuel de luxe (個室高級サウナ), fashion health (ファションヘルス), delivery health(デリバリーヘルス), esthé (エステ), image club (イメージクラブ), mannequin (モデル), hand service(ハンドサービス)...

Comme expliqué dans l'annonce ci dessus, vous pouvez travailler tranquillement : ces entreprises travaillent sous couvert d'entreprise alibi. Autre détail amusant: le salaire est toujours écrit bizarrement: 3,5 puis un kanji qui signifie que l'on parle de quelque chose de plat... Il faut comprendre que l'on parle d'un billet de 10000 yens.


Enfin l'annonce ci dessous propose d'embaucher uniquement des filles rondouillardes (au Japon ça veut dire plus de 60 Kg). Ce qui est marrant ici, c'est le nom de cette maison spécialisée : ぶーとん. La sonorité donne vraiment l'impression de quelque chose de gras et rigolo.

vendredi 14 mars 2008

Etendre PostgreSQL

Pourquoi?

Je travaille en ce moment pour une entreprise de WebAnalytics.

Mon dernier projet a consisté à implémenter un système de recherche en temps réel sur le chemin suivi par chacun des visiteurs entre deux dates données.

Il s'agissait donc de répondre à des questions du type : Parmis les visiteurs qui sont venus en cliquant sur une GoogleAd, combien sont allé jusqu'à la page d'achat d'un produit? Quels sont les pages qu'ils ont vu entre deux?

J'ai finalement opté pour une solution un peu bancale, indépendante de notre base de donnée relationnelle et traditionnelle... au profit toutefois des performances. C'est quelque chose qui ne doit être considéré qu'en dernier recours.

Mon premier réflexe a été d'étendre PostgreSQL, et j'ai étonné de voir que ce n'est pas vraiment difficile et pas si mal documenté. Voici donc un petit tutorial :



Etendre PostgreSQL

Je travaille uniquement sous Mac, Linux Ubuntu et FreeBSD. Ce tutorial a été effectué sous Mac. (Pour installer PostgreSQL sous Mac suiver le guide)


Commencer par créer un fichier "bloompostgres.c" qui contiendra votre méthode. Cette méthode calcule la somme d'un tableau d'entier et la retourne.
Pour implémenter vos propres fonctions, vous pouvez lire la description des types à utiliser en C ici. Vous pouvez aussi lire les fichiers headers que vous trouverez dans
/Library/PostgreSQL8/include/postgresql/server.


#include "postgres.h"
#include "utils/array.h"

int4 sum(IntArray* a)
{
int4 res = 0;
int count = *(ARR_DIMS(a));
ArrayType* arr = a;
int* el = ARR_DATA_PTR(arr);
int i;
for (i = 0; i != count ; i++)
el++;
res += *el;
return res;
}


La compilation s'effectue ensuite par:

gcc -fPIC -c bloompostgres.c -I/Library/PostgreSQL8/include/postgresql/server/
gcc -bundle -flat_namespace -undefined suppress -o bloompostgres.so bloompostgres.o


Il est ensuite possible de charge dynamiquement votre fonction dans PostgreSQL :

 CREATE FUNCTION sum(int[]) RETURNS int4
AS '/Users/paul/Programmation/bloompostgres/bloompostgres', 'sum'
LANGUAGE C STRICT;


Vous pouvez par la suite vous débarasser de cette fonction par :

 DROP FUNCTION sum(int[]);

lundi 11 février 2008

JLPT Niveau 2


Youpi! J'ai obtenu le JLPT niveau 2. Le JLPT (日本語能力試験) c'est l'examen d'aptitude au japonais
le plus connu. Il est divisé en quatre niveaux, 4 étant le plus faible. Il me reste donc à étudier pour passer
le niveau 1. La marche est réputée pour être difficile.

vendredi 28 décembre 2007

Gare de Shinjuku

Comme beaucoup de japonais (3,3 millions semble-t-il), je passe par la gare de Shinjuku tous les jours pour me rendre au bureau. Cette gare concentre une bonne part des lignes du métro et de train qui desservent Tokyo.

Vous pouvez justement voir l'un de ces panneaux sur la photo ci-dessus.
Les quais de la JR -la SNCF japonaise-, sont tous bien rangées parallèment les uns aux autres et deux grandes artères sous-terraines permettent aux voyageurs de passer d'un quai à l'autre. Depuis que je suis arrivé à Tokyo, ce réseau de sous-terrains a toujours eu l'air en travaux : palissades, bâches, et panneaux de fortune (ci-dessus). Et bien ce panneau justement...

Ce panneau est écrit au SCOTCH!


Et il n'est pas le seul... Etonnant non? C'est un peu du réchauffé mais le phénomène avait un peu animé la blogosphère japonaise en 2004... D'autant plus que les lettres sont extrêmement travaillées. Récemment, en flânant sur youtube, je suis tombé sur des reportages amateurs racontant leur histoire. Le monsieur que vous voyez sur la vidéo 1 se réclame d'avoir été le premier, et d'avoir été suivi par ses camarades et encouragés par sa hiérarchie.

Il insiste plusieurs fois sur le fait qu'il a des idées bien arrêtés (こだわり) sur le design qu'il veut donner à ces panneaux.