電卓練習

電卓で計算練習するプログラムを書いてみた。足し算だけだけど、多分引き算も対応できるはず。

#!/usr/bin/perl
# dentaku.pl
#
# 【使い方】
# perl dentaku.pl 最大の数字桁 一問あたりの数 問題数 段組
#
# 【例】
# perl dentaku.pl 10 8 25 5
# 最大10桁の数 一問あたり8つの数 25題出力 段組は5段
#
# 【出力例】
#
#         16, 674, 194         5, 464, 477         8, 861, 287         3, 176, 879        55, 154, 418
#         25, 535, 074        70, 758, 056    1, 631, 164, 550    3, 210, 449, 218        21, 244, 303
#          9, 608, 968         2, 920, 227        14, 941, 406        18, 226, 318         4, 509, 887
#             313, 720        24, 205, 525        92, 483, 520        99, 584, 960         9, 972, 229
#     4, 390, 563, 964         1, 591, 796        95, 446, 777         1, 676, 635         5, 523, 071
#         16, 007, 080        18, 640, 136         4, 974, 975    2, 314, 758, 300    9, 586, 791, 992
#         19, 004, 516    6, 719, 055, 175         5, 868, 835         9, 081, 420         5, 063, 476
#         85, 592, 651    4, 833, 068, 847         8, 082, 885        72, 381, 591         3, 640, 747
# ----------------------------------------------------------------------------------------------------
# (以下略)


use strict;

my @mondaiArray;                # 問題の配列
my @sum;                        # 解答
my ($ketasuu, $tatenokazu, $mondaisuu, $dangumi)  = @ARGV;
$mondaisuu--;
my $space = ($ketasuu + (($ketasuu / 3) * 2)) + 5; # てきとうにスペースを入れる

# ==============================================================================
# メイン
# ==============================================================================
# $mondaisuu分の問題を作成
for (0 .. $mondaisuu) {
    $mondaiArray[$_] = &MakeMondai($ketasuu, $tatenokazu - 1);
}

print "問題\n";
# 配置
for (my $column = 0; $column < $mondaisuu; $column = $column + $dangumi) {
    for (my $row = 0; $row < $tatenokazu; $row++) {
        for (my $line = 0; $line < $dangumi; $line++) {
            printf("%@{[$space]}s", &commma($mondaiArray[$column + $line]->[$row]));
        }
        print "\n";
    }
    print '-'x($dangumi* $space), "\n";
    print "\n\n\n";
}

print "解答\n";
# 解答を出力
for (@mondaiArray) {
    printf("%@{[$space]}s\n", &commma(&SolveMondai($_)));
}
# メインはここまで

# ==============================================================================
# sub routines.
# ==============================================================================
sub MakeMondai {
    my ($ketasuu, $tatenokazu) = @_;
    my $limit = 1;
    my @array;
    # 桁数を作る
    for (my $i = 0; $i < $ketasuu; $i++) {
        $limit = $limit * 10;
    }
    # てきとうな数を作成
    for (0 .. $tatenokazu) {
        my $random = rand();
        my $number;
        if ($random < 0.3) {
            $number  = int(rand($limit));
        } elsif ($random < 0.4) {
            $number  = int(rand($limit) / 10);
        } elsif ($random < 0.6) {
            $number  = int(rand($limit) / 100);
        } elsif ($random < 0.8) {
            $number  = int(rand($limit) / 400);
        } else {
            $number  = int(rand($limit) / 1000);
        }
        push(@array , $number);
    }
    return \@array;
}

sub SolveMondai {
    my ($ref) = @_;
    my $sum = 0;
    $sum += $_ for (@$ref);
    return $sum;
}

sub commma {
    my $num = shift;
    1 while $num =~ s/(.*\d)(\d\d\d)/$1\,\ $2/;
    return $num;
}
# dentaku.pl ends here.

結果はこんな感じ。

問題
         57, 601, 928          9, 617, 614         61, 193, 847     6, 152, 648, 925
         20, 936, 584     2, 602, 539, 062          6, 396, 484          5, 293, 273
          3, 929, 138        653, 900, 146          8, 717, 956          3, 379, 821
         62, 280, 273         12, 058, 258     7, 093, 200, 683        163, 024, 902
     4, 603, 271, 484     4, 503, 173, 828         54, 129, 028         29, 266, 357
         13, 943, 481          6, 077, 575        401, 031, 494          3, 401, 794
         52, 642, 822     3, 594, 055, 175         24, 756, 622         13, 101, 959
         13, 014, 984        522, 979, 736     4, 920, 959, 472        436, 706, 542
--------------------------------------------------------------------------------------



             886, 535         42, 150, 878     8, 556, 213, 378          5, 781, 250
         12, 145, 233     9, 367, 370, 605         68, 429, 565          9, 544, 067
     4, 720, 764, 160     4, 748, 229, 980     9, 253, 845, 214         10, 502, 624
          3, 945, 922          8, 816, 528          5, 355, 834     4, 836, 120, 605
     3, 060, 302, 734         12, 100, 982          2, 142, 333         34, 707, 641
          6, 488, 037          4, 015, 808          7, 843, 933        719, 512, 939
         81, 796, 264          2, 648, 162         15, 600, 585          5, 879, 211
     1, 330, 566, 406         75, 000, 000     4, 739, 685, 058         13, 397, 216
--------------------------------------------------------------------------------------



        612, 670, 898          9, 775, 543         37, 814, 331        697, 326, 660
             548, 553     8, 355, 407, 714          6, 426, 086     6, 145, 019, 531
         99, 475, 097         18, 739, 318         47, 430, 419     2, 730, 712, 890
         76, 293, 945     8, 563, 842, 773     9, 337, 158, 203         99, 484, 252
     4, 855, 651, 855         68, 212, 890        277, 709, 960             841, 369
          4, 906, 005        367, 523, 193     2, 315, 673, 828         20, 031, 738
          5, 422, 973          7, 312, 011         19, 639, 587          8, 124, 084
         20, 664, 978         54, 101, 562         19, 599, 151          5, 120, 086
--------------------------------------------------------------------------------------



          7, 548, 828         86, 544, 799         21, 920, 776          7, 950, 744
          4, 713, 134         10, 702, 514         21, 435, 546     9, 099, 731, 445
          4, 737, 854     8, 316, 345, 214         99, 703, 979     2, 976, 074, 218
          4, 947, 814          9, 685, 974          6, 564, 025          3, 210, 449
     5, 086, 364, 746        679, 351, 806         32, 006, 835     1, 252, 441, 406
          6, 317, 138         85, 388, 183     5, 805, 053, 710         18, 636, 322
          5, 263, 061     6, 769, 409, 179        159, 301, 757         92, 184, 448
         22, 036, 743     6, 401, 672, 363     2, 912, 597, 656          6, 432, 800
--------------------------------------------------------------------------------------



         10, 234, 069         91, 711, 425         13, 723, 754     1, 936, 950, 683
     3, 592, 834, 472         10, 039, 520          1, 748, 962         18, 530, 273
         78, 482, 055     5, 745, 544, 433     4, 721, 069, 335         14, 931, 488
     9, 099, 731, 445          2, 661, 132          2, 825, 927        815, 948, 486
        385, 070, 800          6, 105, 041         15, 808, 105          8, 551, 025
         22, 949, 218          1, 837, 921     1, 690, 979, 003         20, 446, 014
        251, 770, 019     8, 334, 655, 761          8, 901, 977          7, 294, 616
         43, 344, 116          7, 288, 360         36, 495, 971         94, 360, 351
--------------------------------------------------------------------------------------



解答
     4, 827, 620, 694
    11, 904, 401, 394
    12, 570, 385, 586
     6, 806, 823, 573
     9, 216, 895, 291
    14, 260, 332, 943
    22, 649, 115, 900
     5, 635, 445, 553
     5, 675, 634, 304
    17, 444, 915, 004
    12, 061, 451, 565
     9, 706, 660, 610
     5, 141, 929, 318
    22, 359, 100, 032
     9, 058, 584, 284
    13, 456, 661, 832
    13, 484, 416, 194
    14, 199, 843, 593
     6, 491, 553, 034
     2, 917, 012, 936

xyzzyで明朝で9ptで指定したら1ページ内に問題が納まっていい感じに印刷できた。