リズム感を測定するプログラム

30分プログラム、その439。またもmixiの課題丸投げコミュより。

C/C++の課題丸投げ| 構造体についてより。

オリジナル問題-2: リズム感を測定するプログラム

経過時間の測定キーボード入力の時間間隔を測定する.

前回のリターン入力から今回のリターン入力までの経過時間(ミリ秒) を測定する

現在時刻の測定には以下の現在時刻取得関数を用いること.

(Cのコードなので略)

リズム感の判定interval() において測定されたデータを分析しリズム感を判定する.

関数プロトタイプ:

char evaluate(int c, int pitch[], double *avg, double *sigma);
  • 第1引数c: データ数(入力用) (int 型)
  • 第2引数pitch: 時間間隔(入力用) (int 型の配列)
  • 第3引数avg: 平均時間(出力用) (double 型)
  • 第4引数sigma: 標準偏差(出力用) (double 型)

仕様pitch で与えられたc 個のデータを用いて平均値,標準偏差を求める.
戻り値以下の条件によるA,B,C,F の判定結果

  • A: sigmaavg の5%以内の場合
  • B: sigmaavg の10%以内の場合
  • C: sigmaavg の15%以内の場合
  • F: 上記以外の場合

注意平均・分散の計算ではpitch[] を実数として(キャストして) 計算すること

なかなかユニークな問題だと思う。初歩的な内容で作れるし、ゲーム的な要素もあっておもしろい。どこの大学の課題なんだろ。

使い方

$ perl rythm.pl
Ready?
<Enterを6回押す>
$VAR1 = '0.622221';
$VAR2 = '0.534413';
$VAR3 = '0.647064';
$VAR4 = '0.517263';
$VAR5 = '0.606167';

平均 0.5854256
分散 0.0506593029703331

Your rank is ...B!

# チートしてみるw
$ yes | perl 439-rythm.pl
Ready?
$VAR1 = '2.3e-05';
$VAR2 = '3e-06';
$VAR3 = '4e-06';
$VAR4 = '3e-06';
$VAR5 = '3e-06';

平均 7.2e-06
分散 7.90948797331407e-06

Your rank is ...F?

ソースコード

#! /usr/bin/perl
# -*- mode:perl; coding:utf-8 -*-
#
# This program is free software; you can redistribute it and/or
# modify it under MIT Lincence.

use strict;
use warnings;
use Time::HiRes qw(gettimeofday tv_interval);
use List::Util qw(sum);

use Data::Dumper;
sub interval(&){
    my ($f) = @_;
    my $start = [gettimeofday()];
    &$f();
    my $end = [gettimeofday()];
    tv_interval($start,$end);
}

sub pitch($){
    my ($n) = @_;
    if($n == 0){
	();
    }else{
	my $pitch = interval {
	    getc();
	};
	($pitch,&pitch($n-1))
    }
}

sub average(@){
    my (@xs) = @_;
    sum(@xs) / @xs;
}

sub stddev(@){
    my (@xs) = @_;
    my $avg = average(@xs);
    sqrt(sum(map {($_ - $avg)**2} @xs) / @xs);
}

print "Ready?\n";
getc();

my @pitch = pitch(5);
print Dumper(@pitch),"\n";

my $avg = average(@pitch);
my $dev = stddev(@pitch);

print "平均 $avg\n";
print "分散 $dev\n\n";
my $d =$dev / $avg;

print "Your rank is ...";

if($d < 0.05){
    print "A!!!\n";
}elsif($d < 0.10){
    print "B!\n";
}elsif($d < 0.15){
    print "C\n";
}else{
    print "F?\n";
}