Valérie s’est lancée dans une suite de joutes Facebookestes à grands coups de Scramble. Un tableau de 4×4 ou 5×5 avec des lettres, le but du jeu est de dénombrer tous les mots que l’on trouve dedans.

En anglais avec des amies anglophones, bonjour les corrections sur les premières parties.
Petit à petit, Valérie comble son handicap.

Finalement, qu’est-ce que jeu sinon regarder une case, puis ses voisines récursivement ? Ah oui, il ne faut pas repasser deux fois par la même case. Et à la fin il faut vérifier que les mots existent.

Bon.
On sort son Perl favori, et on précise que ce logiciel est sous GPL v3.

Pour vérifier que les mots existent, il existe des listes qui améliorent l’ordinaire du /usr/share/dict/words. Dans ce cas particulier de la liste TWL06.zip, un dos2unix permet d’enlever des sauts de lignes peu linuxiens.

On met les mots en mémoire avec un

open DICT,"< TWL06.txt";
my $dict;
while (<DICT>) {
  chomp($_);
  $dict->{$_}=0;
}
close(DICT);

Il reste un gros bout : parcourir le tableau pour dénombrer les mots candidats.
On commence par récupérer depuis la ligne de commande tapée par l’utilisateur le tableau en question, sous forme d’une chaîne de caractères unique.

my $string = uc(shift());

Avoir la dimension du tableau (combien de lignes = combien de colonnes) est utile par la suite :

my $dimension = int(sqrt(length($string)));

Le Scramble se joue en s’intéressant aux cases adjacentes, on définit donc la métrique (distance entre deux cases) :

sub distance {
  my $x = shift();
  my $y = shift();
  my $dx = abs($x->[0]-$y->[0]);
  my $dy = abs($x->[1]-$y->[1]);
  return ($dx>$dy) ? $dx : $dy;
}

Dans ces conditions, deux cases sont adjacentes si la distance qui les sépare vaut 1. On peut alors créer un hash qui donne donne tous les voisins ($i,$j) de la case ($i0,$j0) :

sub neighbors {
  my $nei;
  for (my $i0=0 ; $i0<$dimension ; $i0++) {
    for (my $j0=0 ; $j0<$dimension ; $j0++) {
      my @a=($i0,$j0);
      for (my $i=0 ; $i<$dimension ; $i++) {
        for (my $j=0 ; $j<$dimension ; $j++) {
          my @b=($i,$j);
          $nei->{$i0.$j0}->{$i.$j}=1 if (distance(\@a,\@b)==1);
        }
      }
    }
  }
  return $nei;
}

my $neighbors=neighbors();

Il nous manque encore la possibilité d’extraire la lettre d’une case donnée. On donne deux entrées possibles à cette fonction, par coordonnées (x puis y) ou en format concaténé (xy) :

sub get_str {
  my $a = shift();
  my $b;
  unless ($b = shift()) { $b=substr($a,1,1); $a=substr($a,0,1); }
  my $res = substr($string,$a+$b*$dimension,1);
  $res=$res."U" if ($res eq "Q");
  return ($res);
}

Au passage, on s’occupe du cas du "Q" qui apparaît toujours sous la forme "QU".

La partie récursive maintenant, celle qui se baladera dans le tableau.

my @allwords;
sub get_neighbors {
  my $a = shift();
  my $b = shift();
  my $depth = shift();
  my $word = shift();
  $word->{$a.$b}=$depth;
  if ($depth==0) {
    push @allwords,$word;
  } else {
    foreach my $nei0 (keys %{$neighbors->{$a.$b}}) {
      next if defined($word->{$nei0});
      my $word0={};
      %$word0=%$word;
      my ($a0,$b0)=(substr($nei0,0,1),substr($nei0,1,1));
      get_neighbors($a0,$b0,$depth-1,$word0);
    }
  }
  return;
}

Si le mot candidat a la longueur souhaitée ($depth à 0), alors on le stocke dans le tableau @allwords en référençant sa taille, pour aider au tri plus tard).
Sinon, on s’intéresse récursivement à ses voisins.

On peut alors lancer la balade dans le tableau à partir de toutes les cases une par une, et pour toutes les longueurs de mots désirées.
Si un mot candidat est référencé dans le hash %$dict, alors on l’imprime à l’écran.

for (my $wordsize=7 ; $wordsize>2 ; $wordsize–) {
  for (my $i0=0 ; $i0<$dimension ; $i0++) {
    for (my $j0=0 ; $j0<$dimension ; $j0++) {
      @allwords=();
      my $word;
      get_neighbors($i0,$j0,$wordsize,$word);
      foreach my $myword ( @allwords ) {
        my @thewords;
        @thewords=sort { $myword->{$b} <=> $myword->{$a} } keys %$myword;
        my $myword = join("",map { get_str($_) } @thewords);
        print($myword,"\n") if (defined($dict->{$myword}));
      }
    }
  }
}

Si on appelle ce script break_scramble, alors on peut trouver les mots anglais entre 3 et 7 lettres compris dans le tableau

a b c d
e f g h
i j k l
m n o p

$ ./break_scramble abcdefghijklmnop
KNIFE
PLONK
MINK
FINK
FINO
JINK
GLOP
KNOP
KOJI


Des optimisations possibles ? Oui, plein. Pour commencer, éviter de repasser par toutes les tailles de mots possibles et imaginables.

Mais en attendant, il devient difficile de perdre les duels Scramble même avec les 30 secondes d’exécution sur un pauvre Pentium 4 HT.

mar 08 2008

Comment Fonctionne Google ?

Guillaume | Geek | 0 Commentaire

Joli article de Michael Eisermann : Comment fonctionne Google ?
Et comme inclure ce lien fait parti de l’expérience…

Notre petit Shuttle Reflexion des familles s’est fait amputer d’un ventilateur de plus, le 4cm qui trônait sur le Northbridge et tournait à 5000 tours par minute. Mignon, mais après l’avoir remplacé trois fois on se lasse.

La carte mère est une SB61, ce qui mine de rien a son importance dans le choix du radiateur qui remplace le ventilateur. En effet, le ZM-NBF47 commandé sur Internet suppose que la carte mère a des boucles d’ancrage "en haut à droite et en bas à gauche" (quand on regarde la carte mère depuis le bus PCI), les intégristes des espaces vectoriels orientés me pardonneront mes approximations. Pas de chance, la SB61 n’a de boucles qu’"en haut à gauche et en bas à droite".

Il faut donc se fendre d’une adaptation sauvage du système d’ancrage du radiateur original de la SB61 par-dessus le ZM-NBF47. Pas très orthodoxe, mais ça marche. Ah, et il faut aussi préciser que le ZM-NBF47 vient avec sa pâte thermique, nul besoin d’essayer de se lancer à la recherche d’un accessoire bien difficile à trouver au pays du froid… Comme de juste, il convient de bien gratter la pâte thermique résiduelle avant de mettre la nouvelle, hein, on est pas des cochons.

Le niveau sonore de la bête a très largement diminué – au point qu’on entend maintenant le disque dur interne. Il faut aussi noter que le ventilateur du CPU s’était déjà fait aménager, pour un plus gros qui tourne moins vite (1000 tours par minute en régime moyen).
Point de vue température, pas de grand changement :

Températures

Le disque dur (placé juste au-dessus du Northbridge) n’a pas beaucoup souffert non plus du changement :

Température Disque Dur

sdb, c’est le disque pour les sauvegardes, celui qui ne s’allume qu’une fois par jour et qui est branché en eSATA dans une boîte séparée de l’unité centrale – et sans ventilateur.
mai 11 2007

Commande du jour

Guillaume | Geek | 0 Commentaire

Au détour de la documentation Debian du paquet mysql, votre serviteur est tombé sur les options de netstat qui répondent élégamment à la sempiternelle question mais qu’est-ce que j’ai comme services qui tournent et sur quels ports

$ sudo netstat -tnpl

mai 06 2007

Bleeding Feisty

Guillaume | Geek | 1 Commentaire

Petit goût de déjà-vu, je sais.

Il existe un bug dans la mise en œuvre de postscript chez Feisty, qui entre autres m’empêchait d’ouvrir mon fichier OpenOffice de l’article publié récemment dans Linux Magazine 94.
Le problème est connu, et peut être contourné comme suit :
$ sudo apt-get install gs-gpl
$ sudo update-alternatives –config gs

[ choisir gs-gpl ]

Difficile à manquer, comme bug, compte-tenu de l’omniprésence de postscript dès qu’on veut échanger des graphiques entre applications. Bug ouvert en décembre 2006, tout de même.

Dans la même veine, Monsieur Feisty se targue de geler régulièrement l’ensemble de l’ordinateur sans crier gare. Suspects en cours d’investigation : ivtv et SMP (réintroduction d’un bug passé) ou vmware serveur (dont il faut modifier cavalièrement les sources des modules noyaux pour qu’ils veuillent bien compiler).

En-dehors de ces deux animaux-là, le passage à Feisty s’est avéré beaucoup plus calme que celui à Edgy. Ouf !

Dans la liste des un jour il faudra que, quitter Tetex pour Texlive (toujours dans Universe, donc il n’y a pas le feu).

déc 18 2006

Un O’Reilly à $0.99

Guillaume | Geek | 4 Commentaire(s)

On se demande bien pourquoi personne ne voudrait acheter un bouquin sur SCO Unix, fût-ce un O’Reilly à $0.99 !

nov 02 2006

Bleeding Edgy

Guillaume | Geek | 1 Commentaire

Maître Guillaume, sur un MythTV perché,
Tenait en son bec un Dapper bien stabilisé.
Bleeding Edgy, par l’odeur alléché,
Lui tint à peu près ce langage :
« Hé ! Bonjour, monsieur du Guillaume.
Que votre MythTV est bien stable ! Que vous me semblez productif !
Sans mentir, si vous passiez à Edgy,
Vous auriez Beryl, Firefox 2 et ivtv tout fourni »
À ces mots, le Guillaume ne se sent plus de joie ;
Et pour récupérer tous ces paquets,
Il entame sa mise à jour, et perd sa stabilité.

Le Bleeding Edgy s’en saisit, et dit : « Mon bon Monsieur,
Apprenez que tout flatteur
Vit aux dépens de celui qui l’écoute :
Cette leçon vaut bien une télécommande cassée, sans doute.
Assortie d’un lecteur de cartes inopérant,
d’un Clié à la synchronisation hasardeuse
d’un ACPI malade
d’un remboursement anticipé de la dette bashiste
et d’un mode console ruiné. »

Le Guillaume, honteux et confus,
Jura, mais un peut tard, qu’on ne l’y prendrait plus.

Notre bon Shuttle (ordinateur) se comporte comme tous les systèmes ventilés du monde.
Silencieux et froid au début, il prend la poussière, perd de l’efficacité, commence à faire du bruit.

Nico a lancé l’offensive, à grands coups de Fry’s et de Home Depot. Si vous la lui demandez gentillement, je suis sur qu’il vous donnera la kit list.

Cette semaine, la première phase est lancée : je suis allé faire mes courses suivant ses indications, et j’ai configuré la collecte des informations objectives sur l’état de refroidissement de la boiboite.

Mode d’emploi, pour un Ubuntu Dapper :

  1. Installer les paquets lm-sensors (libsensors3, lm-sensors, sendord et pourquoi pas sensors-applet)
  2. Patcher le binaire /usr/sbin/sensors-detect (patch -p1/usr/sbin/sensors-detect < chemin_vers_le_fichier_avec_le_patch)
  3. Lancer en root sensors-detect, en répondant oui à tout. J’utilise le bus isa, mais les goûts et les couleurs, hein…
  4. Charger les modules noyau : sudo /etc/init.d/module-init-tools start
  5. Vérifier via l’utilitaire sensors que les mesures marchent
  6. Intégrer le tout à munin :

user@host:/etc/munin/plugins$ sudo /usr/share/munin/plugins/sensors_ suggest
fan
volt
temp
user@host:/etc/munin/plugins$ sudo ln -s /usr/share/munin/plugins/sensors_ sensors_far
user@host:/etc/munin/plugins$ sudo ln -s /usr/share/munin/plugins/sensors_ sensors_volt
user@host:/etc/munin/plugins$ sudo ln -s /usr/share/munin/plugins/sensors_ sensors_temp

Et là, oh magie, les graphiques commencent à arriver chez munin :

Ventilateurs
températures
Tensions

Et tant qu’on y est, ce qu’ACPI nous donnait déjà, la température du microprocesseur :

Température CPU

La phase de collecte des informations subjectives était déjà bien avancée, elle. 6 mois que je me dis qu’il est trop bruyant, mon Shuttle…

Suite, la semaine prochaine, l’opération de la bête.

juil 25 2006

Décalage aéronautique

Guillaume | Cloé, Geek | 0 Commentaire

Sept heures de décalage, me voilà réveillé par Princess aux alentours de 4 heures du matin. Après avoir rapidement renoncé à retrouver Morphée (elle s’est bien planquée, celle-là), je me résouds à remettre la sortie SVideo de mon PVR 350 sur pieds.

Cela va sans dire, Dapper me l’avait cassée, en utilisant une version de X.Org qui ne comprenait plus le ivtvdev_drv (pilote X) pré-compilé. À la clef, des problèmes de symboles non-résolus:
Required symbol shadowAdd from module /usr/lib/xorg/modules/ivtvdev_drv.o is unresolved!
et autres gentillesses.

Solution, recompiler (pas drôle du tout), ou bien ceci: http://www.hellion.org.uk/ivtv

mai 11 2006

Calculette Google

Guillaume | Geek | 0 Commentaire

Le moteur de recherche de Google fait aussi calculatrice… et plutôt bien !
Par exemple, si on…

Non, elle ne fait pas de calcul symbolique, et ne résoud pas les équations – faut pas pousser, quand même !

© 2007 Au petit plombier | Wordpress | Gallerie | dKret2 2.1 | WPG2 Optimized | XHTML | CSS | Haut |