vallog: [1,2,3,4,5] が与えられたとき [[1,2][2,3][3,4][4,5]] を返すような関数を定義せよ
を Perlで解いてみた。
プログラム
こんな感じでしょうか。モジュールは特に使ってないです。素のperlでも
もう少しエレガントな回答があるかもしれないですね。
#!/usr/bin/env perl use strict; use warnings; sub overlap_slices { my ($array_ref, $length) = @_; die "argument is undef\n" unless defined $array_ref; $length ||= 2; my @array = @{$array_ref}; my $ret = []; while (scalar @array >= $length) { my @cars = splice @array, 0, ($length - 1); my $cadr = $array[0]; push @{$ret}, [@cars, $cadr]; } my $reminder = scalar @array; push @{$ret}, [@array] if $reminder > 1 && $reminder <= ($length - 1); return $ret; }
テスト
ちゃんとテストファーストでやったら、やっぱり効率的ですね。
use Test::More; my ($got, $expected); $got = overlap_slices([]); is_deeply($got, [], "empty array"); $got = overlap_slices([0, 1]); is_deeply($got, [[0, 1]], "only two elements"); $expected = [ [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], ]; $got = overlap_slices([0..5]); is_deeply($got, $expected, "default length 2"); $got = overlap_slices([0..9], 2); $expected = [ [0,1], [1,2], [2,3], [3,4], [4,5], [5,6], [6,7], [7,8], [8,9], ]; is_deeply($got, $expected, "length is 2"); $got = overlap_slices([0..9], 3); $expected = [ [0..2], [2..4], [4..6], [6..8], [8,9], ]; is_deeply($got, $expected, "length is 3"); $got = overlap_slices([0..9], 4); $expected = [ [0..3], [3..6], [6..9], ]; is_deeply($got, $expected, "length is 4"); $got = overlap_slices([0..9], 5); $expected = [ [0..4], [4..8], [8,9], ]; is_deeply($got, $expected, "length is 5"); $got = overlap_slices([0..9], 6); $expected = [ [0..5], [5..9], ]; is_deeply($got, $expected, "length is 6"); $got = overlap_slices(['a'..'z'], 10); $expected = [ ['a'..'j'], ['j'..'s'], ['s'..'z'], ]; is_deeply($got, $expected, "length is 10"); done_testing;
テスト結果
% prove -v test1.pl test1.pl .. ok 1 - empty array ok 2 - only two elements ok 3 - default length 2 ok 4 - length is 2 ok 5 - length is 3 ok 6 - length is 4 ok 7 - length is 5 ok 8 - length is 6 ok 9 - length is 10 1..9 ok All tests successful. Files=1, Tests=9, 0 wallclock secs ( 0.03 usr 0.00 sys + 0.02 cusr 0.00 csys = 0.05 CPU) Result: PASS
正しいようです。