2012/05/18

逆FizzBuzz問題 (Inverse FizzBuzz) - 猫とC#について書くmatarilloの雑記

逆FizzBuzz問題 (Inverse FizzBuzz) General | Inverse Fizzbuzz - just another scala quant を日本語にしました。 ちなみに...

http://d.hatena.ne.jp/matarillo/20120515/p1
逆FizzBuzzって、オートマトンなので正規表現を使うと楽に出来るはず。 #!perl
use strict;
use warnings;
use Test::More;

sub inv_fizzbuzz {
  my ($fz, $n, $pat) = ('', 1, join ',*?', @_);
  while (1) {
    $fz .= $n % 15 > 0 ?
             $n % 3 > 0 ?
               $n % 5 > 0 ?
                 ',': 'buzz,': 'fizz,': 'fizzbuzz,';
    if ($fz =~ /,($pat)/) {
      my $rhs = $1;
      my $lhs = substr($fz, 0, index($fz, $rhs) + 1);
      $lhs =~ s/(fizz|buzz)//g;
      $rhs =~ s/(fizz|buzz)//g;
      $lhs = length($lhs);
      $rhs = $lhs + length($rhs||'');
      return [$lhs, $rhs];
    }
    $n++;
  }
}

is_deeply(inv_fizzbuzz('fizz'), [3, 3]);
is_deeply(inv_fizzbuzz('buzz'), [5, 5]);
is_deeply(inv_fizzbuzz('fizz', 'buzz'), [3, 5]);
is_deeply(inv_fizzbuzz('buzz', 'fizz'), [5, 6]);
is_deeply(inv_fizzbuzz('fizz', 'fizz', 'buzz'), [6, 10]);
is_deeply(inv_fizzbuzz('fizz', 'fizz'), [6, 9]);
is_deeply(inv_fizzbuzz('fizz', 'buzz', 'fizz'), [3, 6]);
is_deeply(inv_fizzbuzz('fizzbuzz', 'fizz'), [15, 18]);

done_testing;
追記1
Vimだとこうか?
function! s:inv_fizzbuzz(...)
  let [fz, n, p] = ['', 1, join(a:000, ',\{-}')]
  while 1
    let fz .= n%15>0?n%3>0?n%5>0?",": "buzz,": "fizz,": "fizzbuzz,"
    let m = matchstr(fz, p)
    if len(m) > 0
      let lhs = len(split(fz[:stridx(fz, m)-1], ',', 1))
      return [lhs, lhs + len(split(m, ',', 1))-1]
    endif
    let n += 1
  endwhile
endfunction

追記2
ちょっと改良。方針は変わってない。
#!perl
use strict;
use warnings;
use Test::More;

my $gs = 'AAFAABAFAAAFABAAFAAAZ';

sub inv_fizzbuzz {
  my ($fz, $n, $pat) = ('', 1,
    join('A*?', map({fizz=>'F', buzz=>'B', fizzbuzz=>'Z'}->{$_}, @_)));
  my $m;
  while (1) {
    $fz .= $n % 15 > 0 ?
             $n % 3 > 0 ?
               $n % 5 > 0 ?
                 'A': 'B': 'F': 'Z';
    last if length($fz) > length($gs) * length(@_);
    if ($fz =~ /^.*($pat)$/) {
      my $rhs = $1;
      my $lhs = substr($fz, 0, rindex($fz, $rhs) + 1);
      $m = [$lhs, $rhs] if !defined($m) || length(@{$m}[1]) gt length($rhs);
    }
    $n++;
  }
  return [] unless $m;
  
  my ($lhs, $rhs) = @{$m};
  $lhs = length($lhs);
  $rhs = $lhs + length($rhs||'') - 1;
  return [$lhs, $rhs];
}

is_deeply(inv_fizzbuzz('fizz'), [3, 3]);
is_deeply(inv_fizzbuzz('buzz'), [5, 5]);
is_deeply(inv_fizzbuzz('fizz', 'buzz'), [9, 10]);
is_deeply(inv_fizzbuzz('buzz', 'fizz'), [5, 6]);
is_deeply(inv_fizzbuzz('fizz', 'fizz', 'buzz'), [6, 10]);
is_deeply(inv_fizzbuzz('fizz', 'fizz'), [6, 9]);
is_deeply(inv_fizzbuzz('fizz', 'buzz', 'fizz'), [3, 6]);
is_deeply(inv_fizzbuzz('fizzbuzz', 'fizz'), [15, 18]);
is_deeply(inv_fizzbuzz('fizzbuzz', 'fizz'), [15, 18]);
is_deeply(inv_fizzbuzz('buzz', 'buzz'), []);

done_testing;
vimスクリプト版はkoronさんが書いてた。
koron/zzub-zzif-vim ツキ GitHub
https://github.com/koron/zzub-zzif-vim
Posted at 17:36 | WriteBacks () | Edit
Edit this entry...

wikieditish message: Ready to edit this entry.






















A quick preview will be rendered here when you click "Preview" button.