エントリー

※注意:このエントリーは、旧日記「みおだいあり~」からデータを移管したものです。

[Perl] Perl30分間トレーニング#2

Perl30分間トレふつかめ。

今回挑んだ問題は、前回に引き続き↓これ↓。

さっそく、俺ルールのうち一つ「30分たったら、いくら途中でもそこで今日はおしまい。」を破ってしまいました;
 いや、だって、すっきりしたかったんだもん!

問題6の答案
#! /usr/local/bin/perl
chomp ($n = <>);
&calc_DI($n, 65, 70);
sub calc_DI {
	my ($u, @d) = @_;
	foreach my $i (@d) {
		printf "%.1f\n", ($i + 0.143 * $u - 46.3) / (0.81 + 0.0099 * $u);
	}
}

 

そして、問題7なのですが、さらに40分オーバーも時間をかけて解いてみたのですが、答えが合いません・・・orz...
 私の「間違っている答案」を下に晒しておきますので、どこがおかしいのか、教えてエロい人!

問題7の答案 (誤り)
#! /usr/local/bin/perl
$[ = 1, $i = 1;
$lu = {l=>[[1,0],[0,1]], u=>[[0,0],[0,0]]};
$z = [[0],[0]];
while (<>) {
	chomp $_;
	push (@input_data, $_);
}
for $j (a..f) {
	$p{$j} = @input_data[$i++];
} $rp = \%p;
$lu -> {u} -> [1][1] = $$rp{a};
$lu -> {u} -> [1][2] = $$rp{b};
$lu -> {u} -> [2][2] = -$lu -> {u} -> [1] -> [2] * $lu -> {l} -> [2] -> [1] + $$rp{e};
$lu -> {l} -> [2][1] = $$rp{d} / $lu -> {u} -> [1] -> [1];
$z -> [1][1] = $$rp{c};
$z -> [2][1] = $$rp{f} - $lu -> {l} -> [2] -> [1] * $z -> [1] -> [1];
$y = $z -> [2] -> [1] / $lu -> {u} -> [2] -> [2];
$x = ($z -> [1] -> [1] - $lu -> {u} -> [1] -> [2] * $y) / $lu -> {u} -> [1] -> [1];
printf "%.3f, %.3f\n", $x, $y;

20行と短いですが、リファレンス(C言語でいうところのポインタ)の使い過ぎで、頭が痛くなってきました…。

#####コメント#####

本日のツッコミ
たこ (2008年10月23日(Thu) 23:09)
C++で6だけ解いてみました。
#include <iostream>
#include <iomanip.h>
using namespace std;

int main(){
        
        double s;
        
        cin >> s;
        cout << setprecision(3) << (65 - 46.3 + 0.143 * s)/(0.81 + 0.0099 * s) << "\n" << (70 - 46.3 + 0.143 * s)/(0.81 + 0.0099 * s);
        
        return 0;
} 
あずま (2008年10月24日(Fri) 03:23)
lapackをry
LU分解でぐぐるといいと思うよ。perlは読む気しないのでC#版を置いておきますね。数万点でテストしているので間違ってないはず。エラー処理は省略。
using System;
class Program {
    const double eps = 1.0e-10; // ゼロ判定のしきい値
    static void Main() {
        double[][] a = new double[2][] {
            new double[] { 1.0, 2.0 },
            new double[] { 4.0, 5.0 } };
        double[] b = new double[2] { 3.0, 6.0 };
        double[] x = new double[2];
        
        CalcLu(a, b, x);
        foreach(double d in x)
            Console.WriteLine(d);
    }

    static void CalcLu(double[][] a, double[] b, double[] x) { // bとxが分けてあるのは趣味
        int u = a[0].Length;
        int v = a.Length;
        for(int i = 0; i < v; i++) {
            if(Math.Abs(a[i][i]) < eps) { // ピボット選択
                for(int j = i + 1; j < v; j++)
                    if(eps <= Math.Abs(a[j][i])) {
                        double[] t = a[i];
                        a[i] = a[j];
                        a[j] = t;
                        goto endPibot;
                    }
                throw new Exception("解が存在しません");
            }
        endPibot:
            for(int j = i + 1; j < v; j++) {
                double d = a[j][i] / a[i][i];
                a[j][i] = d;
                for(int k = i + 1; k < u; k++)
                    a[j][k] = (a[j][k] - d * a[i][k]);
            }
        }

        // 前進消去
        double[] y = new double[v];
        for(int i = 0; i < v; i++) {
            y[i] = b[i];
            for(int j = 0; j < i; j++)
                y[i] -= a[i][j] * y[j];
        }

        // 後退代入
        for(int i = v - 1; 0 <= i; i--) {
            x[i] = y[i];
            for(int j = u - 1; i < j; j--)
                x[i] -= a[i][j] * x[j];
            x[i] /= a[i][i];
        }
    }
} 
たこ (2008年10月24日(Fri) 12:31)
1のソースはNYSLです
たこ (2008年10月24日(Fri) 12:37)
修正しました。これもNYSLです。
#include <iostream>
#include <iomanip.h>
using namespace std;

double tempra(double s, int d){
        return (d - 46.3 + 0.143 * s)/(0.81 + 0.0099 * s);
}

int main(){
         
        double s;
         
        cin >> s;
        cout << setprecision(3) << tempra(s, 65) << "\n" << tempra(s, 70) << endl;
         
        return 0;
} 
みお (2008年10月24日(Fri) 22:03)
> azumayaさん 
すばらしい答案、ありがとうございます!。
連立方程式の解が一意に存在する、と問題文中にあるにも関わらず、解が存在するかしないかの処理まで付いていて、ものすごく丁寧なコーディングに感動しました!

   > tako
「たこ」も「NYSL」だよね?
じゃぁ、たこ焼き・・・。じゅるり。
たこ (2008年10月24日(Fri) 23:38)
「たこ」は食べれません><

ページ移動

コメント

  • コメントはまだありません。

コメント登録

  • コメントを入力してください。
登録フォーム
名前 *
URL
コメント *
閲覧制限 *
【スパム対策】 2 × 2 × 2 = ? (半角数字で)

ユーティリティ

user profile

calendar

042024/0506
S M T W T F S
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 -

tag cloud