Games::Puzzles::SendMoreMoneyを試してみた

30分プログラム、その357。CPANにあるSEND+MORE=MONEY専用モジュールのGames::Puzzles::SendMoreMoneyを試してみた。

# Log4perlを入れないと使えない。依存関係のミス?
cpan> install Log::Log4perl
cpan> install Games::Puzzles::SendMoreMoney

SとMが0以外とかいう条件を毎回書くのが面倒だったので、項の頭のアルファベットは0以外であるという条件を決め打ちにした。
正直、速度がいまひとつな気がする。

使い方

$ time perl money.pl "SEND + MORE = MONEY"
$VAR1 = {
          'S' => 9,
          'O' => 0,
          'M' => 1,
          'D' => 7,
          'N' => 6,
          'R' => 8,
          'E' => 5,
          'Y' => 2
        };
perl money.pl "SEND + MORE = MONEY"  32.67s user 0.50s system 97% cpu 34.034 total
$ time perl money.pl "HACKER * 3 = ENERGY"
$VAR1 = {
          'A' => 0,
          'N' => 1,
          'K' => 4,
          'E' => 6,
          'Y' => 9,
          'H' => 2,
          'C' => 5,
          'R' => 3,
          'G' => 8
        };
perl money.pl "HACKER * 3 = ENERGY"  7.23s user 0.14s system 95% cpu 7.677 total

ソースコード

#! /usr/bin/perl
# -*- mode:perl; coding:utf-8 -*-
#
# money.pl -
#
# Copyright(C) 2008 by mzp
# Author: MIZUNO Hiroki / mzpppp at gmail dot com
# http://howdyworld.org
#
# Timestamp: 2008/08/28 00:10:07
#
# This program is free software; you can redistribute it and/or
# modify it under MIT Lincence.
#
use strict;
use warnings;
use Data::Dumper;

use Games::Puzzles::SendMoreMoney;

sub solve($){
    my ($expr) = @_;
    my @non_zero = $expr =~ /(?:\W|^)([A-Z])/g;
    my $solver = Games::Puzzles::SendMoreMoney->new(
	   values =>[0..9],
     puzzle => $expr,
     reporter => sub {print Dumper($_[0]); exit(0);},
     validator => sub {
       my ($ans) = @_;
       foreach my $c (@non_zero){
         return 0 if $ans->{$c} == 0;
       }
       return 1;
     });
    $solver->solve();
}

solve($ARGV[0]);