【プログラム クイズ】

1.以下のプログラムを作ってみて下さい。


 3つの整数を入力し、それを辺とする三角形が、正三角形、二等辺三角形、不等辺三角形のどれであるかを出力する。


 例:3辺の長さを入力してください
   (3,4,5を入力)
   不等辺三角形です。


2.上記のプログラムをテストするのに必要なテストケースを全て挙げてみて下さい。

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2011/02/27 19:14:23
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:imo758 No.2

回答回数121ベストアンサー獲得回数19

ポイント105pt

1.

# http://codepad.org/jHjcxfTu
sub triangle_test{
  my($a, $b, $c) = @_;
  if(triangle_check($a, $b, $c)){ #不要なら外す
    print "非三角形($a, $b, $c)\n";
  }elsif($a == $b and $b == $c){
    print "正三角形($a, $b, $c)\n";
  }elsif($a != $b and $b != $c and $c != $a){
    print "不等辺三角形($a, $b, $c)\n";
  }else{
    print "二等辺三角形($a, $b, $c)\n";
  }
}

&triangle_test(1 + int rand 4,1 + int rand 4,1 + int rand 4) for(1..30);

sub triangle_check{
  my($a, $b, $c) = sort {$a <=> $b}@_;
  return ($a + $b > $c ? 0: 1);
}

2.日曜プログラミングならテストケースもこの程度でいいと思いますが

意地悪な入力に対しては、そもそも耐えられるようにはなっていません

id:garyo

ありがとうございます。

>意地悪な入力に対しては、そもそも耐えられるようにはなっていません

この問題は意地悪なテストケースをどこまで考えられるかという問題でした。

プログラムは正解ですが、テストケースは不十分になります。

例として、3辺が全て0の場合が抜けています。

(出題は「3つの整数」なので0も含みます)

2011/02/27 18:17:57

その他の回答5件)

id:taknt No.1

回答回数13539ベストアンサー獲得回数1198

ポイント55pt

エクセルVBAです。

セルA1、B1、C1にそれぞれ数値を入れて実行させてください。

もちろんチェックはしてませんので文字列や値は 0でも 実行はできますけどね、

今回は 三角形のどれかを 出すという条件があるので 必ず0より大きい整数を入力した場合と

限定させてもらいます。

限定しない場合は、0より大きい整数か判定し、該当しない場合は、三角形にならないと

判断されてその旨のエラーを出すことになります。



Sub check()
a = Cells(1, "A")
b = Cells(1, "B")
c = Cells(1, "C")

If a = b And b = c Then
    MsgBox ("正三角形")
    Exit Sub
End If

If a = b Or b = c Or a = c Then
    MsgBox ("二等辺三角形")
    Exit Sub
End If

MsgBox ("不等辺三角形")

End Sub

必要なテストケース

(3,3,3を入力) 三辺が同じ

(3,4,4を入力) 二辺が同じ

(4,3,4を入力) 二辺が同じ

(4,4,3を入力) 二辺が同じ

(3,4,5を入力) 三辺がみな違う

id:garyo

ありがとうございます。

残念ですが、テストケースもプログラムも不正解となります。

例として、

(1, 1, 3を入力)があります。

この場合は、「3角形の2辺の和は他の1辺より長い」という条件を満たさないため、三角形になりません。

2011/02/27 18:04:38
id:imo758 No.2

回答回数121ベストアンサー獲得回数19ここでベストアンサー

ポイント105pt

1.

# http://codepad.org/jHjcxfTu
sub triangle_test{
  my($a, $b, $c) = @_;
  if(triangle_check($a, $b, $c)){ #不要なら外す
    print "非三角形($a, $b, $c)\n";
  }elsif($a == $b and $b == $c){
    print "正三角形($a, $b, $c)\n";
  }elsif($a != $b and $b != $c and $c != $a){
    print "不等辺三角形($a, $b, $c)\n";
  }else{
    print "二等辺三角形($a, $b, $c)\n";
  }
}

&triangle_test(1 + int rand 4,1 + int rand 4,1 + int rand 4) for(1..30);

sub triangle_check{
  my($a, $b, $c) = sort {$a <=> $b}@_;
  return ($a + $b > $c ? 0: 1);
}

2.日曜プログラミングならテストケースもこの程度でいいと思いますが

意地悪な入力に対しては、そもそも耐えられるようにはなっていません

id:garyo

ありがとうございます。

>意地悪な入力に対しては、そもそも耐えられるようにはなっていません

この問題は意地悪なテストケースをどこまで考えられるかという問題でした。

プログラムは正解ですが、テストケースは不十分になります。

例として、3辺が全て0の場合が抜けています。

(出題は「3つの整数」なので0も含みます)

2011/02/27 18:17:57
id:rsc96074 No.3

回答回数4503ベストアンサー獲得回数437

ポイント95pt

 こちらはいかがでしょうか。我流で読みにくく、なんかへんなプログラムですが、とりあえず動くみたいです。(^_^;

1.

/* TriAngleTest.c */
#include <stdio.h>

#define ABS(x)	((x)< 0  ? -(x) : (x))
	
int main(void)
{
	int a,b,c;	/* 3辺 */
	
	printf("3辺の長さを入力してください。(整数 a,b,c)\n");
	scanf("%d,%d,%d%*[^\n]%*c",&a,&b,&c);
	
	if(ABS(b-c)<a && a<b+c)	/* 三角不等式 */
		;	/* 何もしない。(^_^; */
	else{
		printf("Error!\n");
		return(1);
	}
	
	switch((a==b)+(b==c)+(c==a)){
		case 3:
			printf("正三角形です。\n");
			break;
		case 1:
			printf("二等辺三角形です。\n");
			break;
		case 0:
			printf("不等辺三角形です。\n");
			break;
	}
	
	return(0);
}

2.

(1)1,1,1→正三角形です。

(2)1,2,2→二等辺三角形です。

(3)3,4,5→不等辺三角形です。

(4)1,2,3→Error!

id:garyo

ありがとうございます。

プログラムは正解ですが、テストケースは不十分になります。

例として、3辺が全て0の場合が抜けています。

(出題は「3つの整数」なので0も含みます)

2011/02/27 18:35:16
id:snmp No.4

回答回数20ベストアンサー獲得回数1

ポイント5pt

Perlで書いてみました。

ハッシュの特性を利用し入力された数値の重複数をカウントしてます。

※入力のエラーチェックは入れてません。。。


#!/usr/bin/perl

use strict;
use warnings;

my @input = @ARGV;
my %data = ();
###################
# 重複数チェック
###################
foreach my $value(@input){
        $data{$value}++;
}

###################
# 重複数で振り分け
###################
my @count = reverse(sort values(%data));
if($count[0] == 1){
        print '不等辺三角形'."\n";
}
if($count[0] == 2){
        print '二等辺三角形'."\n";
}
if($count[0] == 3){
        print '正三角形'."\n";
}

exit;
id:garyo

ありがとうございます。

>※入力のエラーチェックは入れてません。。。

恐らく、プログラムの方は三角不等式のチェックが無いと思います。また、入力が正の整数以外の時のチェックも抜けていると思います。(Perlは良くわかりません)

また、テストケースが書いてありません。

2011/02/27 18:40:02
id:ita No.5

回答回数204ベストアンサー獲得回数48

ポイント45pt

素直に考えます。

#include <stdio.h>
char *print_msg(int a, int b, int c)
{
    int ns = 0;
    if (a==b) ns++;
    if (b==c) ns++;
    if (c==a) ns++;

    switch(ns)
    {
        case 3: return "正三角形";
        case 1: return "二等辺三角形";
        case 0: return "不等辺形";
        default:
        printf("エラー! ns=%d\n", ns);
    }
    return "";
}

void main(int argc, char **argv)
{
    int a = atoi(argv[1]);
    int b = atoi(argv[2]);
    int c = atoi(argv[3]);
    printf("%sです\n", print_msg(a,b,c));
}

てな感じでしょうか。

テストデータは

3 3 3

2 3 3

3 2 3

3 3 2

1 2 3

の5つあたりで。

id:garyo

ありがとうございます。

>素直に考えます。

残念ですが素直すぎます(^^;)

プログラムの方は入力が正の整数以外時のチェックと三角不等式が抜けているため、不正解となります。

テストケースも不十分になります。

例として、3辺が全て-1の場合、「正三角形」と表示します。

http://codepad.org/udgTsfjV


後、入力後の結果も必要になります。

例えば5番目の(1, 2, 3)は1+2=3なので直線になります

2011/02/27 19:11:13
id:holoholobird No.6

回答回数574ベストアンサー獲得回数104

ポイント5pt

import java.util.*;

public class tri {


public static void main(String[] args) {

Scanner stdIn = new Scanner(System.in);

System.out.println("3辺の長さを入力してください");

int x=stdIn.nextInt();

int y=stdIn.nextInt();

int z=stdIn.nextInt();

if(x==y||x==z){

if(x==y&&x==z){

System.out.println("正三角形です");

}else{

System.out.println("二等辺三角形です");

}

}else{

System.out.println("不等辺三角形です");

}

}

}


どうでしょう

id:garyo

ありがとうございます。

プログラムの方は入力が正の整数以外時のチェックと三角不等式が抜けているため、不正解となります。

テストケースも回答願います。実はこの問題はそちらの方がメインでした(^^;)。

2011/02/27 18:49:47
  • id:garyo
    それでは、このあたりで締切りにしたいと思います。
    この問題は「Myersの三角形」といい、テストケースを正しく作成できるかという点がポイントになります。
  • id:garyo
    回答はこちらを正解とします。
    http://www.ogis-ri.co.jp/otc/hiroba/Report/ESEC2003/quality.html
    Myersの三角形の解答:

    ポイント配分は以下のようにします。

    参加ポイント:5ポイント
    プログラムに三角不等式の判定あり:50ポイント
    上記を満たすテストケース1つにつき10ポイント
  • id:garyo
    imo758さんにいるかを贈呈します。
    rsc96074さんもプログラムは正解でしが、テストケースの数でポイント数が下がってしまいました。
    1番の正解者は上記2名の方ですが、2番の正解者は居られませんでした。
  • id:taknt
    >3つの整数を入力し、それを辺とする三角形が、正三角形、二等辺三角形、不等辺三角形のどれであるかを出力する。

    ということなので 三角形として条件を満たさないものは 入力されないということで
    作成しました。

    つまり 必ず
    >正三角形、二等辺三角形、不等辺三角形のどれであるかを出力する。
    プログラムを作ったわけです。
  • id:softest
    三角不等式は、

     a<b+c

    だと、桁あふれしちゃうというのも忘れちゃいそうですね。
  • id:garyo
    takntさん、こんにちは。

    この問題は実はひっかけ問題(^^;)で、takntさんにはきっちりひっかかって頂いて嬉しかったです。


    「三角形と書いてあるので、必ず正の整数が入力されるはず(実際には問題には「整数」としか書いてないので0や負の整数の入力もありうる)」や


    「三角形と書いてあるので、三角形という条件を満たすもののみ入力される(しかし、入力条件は「3つの整数」なので三角形の条件を満たさないものを入力することは可能で、入力時の異常判定の実装、及びテストケースによる検証)がされているか」
    という思い込みがないかどうかを確認するのが、この問題の本質です。


    プログラマの場合(私も含めて)、「三角形だから入力は正の整数にきまってる!」と無意識に判断することが多くて、他者によるテスト時に「整数だから0の入力もありだよね」と0の入力でバグが見つかるというのは良くあります。


    takntさんの場合は、以下のように書かれていますので、「正の整数以外の判定」の実装はありませんが、「仕様により使用条件を設定している」と判断しました。


    >もちろんチェックはしてませんので文字列や値は 0でも 実行はできますけどね、
    >今回は 三角形のどれかを 出すという条件があるので 必ず0より大きい整数を入力
    >した場合と限定させてもらいます。


    ここで、「入力は三角形の条件(三角不等式を満たすもの)のみに限る」と回答で使用条件に縛りが入っていれば、以下もありだったのですが……


    >>3つの整数を入力し、それを辺とする三角形が、正三角形、二等辺三角形、不等辺
    >三角形のどれであるかを出力する。
    >
    >ということなので 三角形として条件を満たさないものは 入力されないということで
    >作成しました。
    >
    >つまり 必ず
    >>正三角形、二等辺三角形、不等辺三角形のどれであるかを出力する。
    >プログラムを作ったわけです
  • id:garyo
    softestさん、こんにちは。

    >三角不等式は、
    > a<b+c
    >だと、桁あふれしちゃうというのも忘れちゃいそうですね。
    確かにそうですね。
    http://juichi.blog.so-net.ne.jp/2005-04-16
    上記でも書かれていますが、Myersの模範解答とは違う正解も色々ありそうですね。
    (しかもcだとエラーになるが、Rubyだと多倍長整数に自動で切り替わるのでエラーにならないとか)
  • id:taknt
    >ここで、「入力は三角形の条件(三角不等式を満たすもの)のみに限る」と回答で使用条件に縛りが入っていれば、以下もありだったのですが……


    記載漏れにあとで 気づきました。

    ま、仕様自体にも 三角形に該当しない場合の仕様が漏れてましたので おあいこかと思いました(笑)

  • id:garyo
    imo758さんとrsc96074さんのどちらにいるかを差し上げるかは正直迷ってました。
    imo758さんの乱数を使ったテストというのは、下手をすると、「たまたま必要なテスト条件が発生しない」(例えば全てが正三角形になる)恐れもあるわけです。また、入力に対して何が正しい結果なのかの定義がありませんでした。


    rsc96074さんの
    (2)1,2,2→二等辺三角形です。
    に後、(2,1,2)と(2,2,1)のテストケースが含まれていれば逆転していたと思います。
  • id:imo758
    # http://codepad.org/3YxpkFjV
    for$a(-2..4){
    for$b(-2..4){
    for$c(-2..4){
    &triangle_test($a, $b, $c);
    }
    }
    }

    sub triangle_test{
    my($a, $b, $c) = @_;
    if(triangle_check($a, $b, $c)){ #不要なら外す
    print "非三角形($a, $b, $c)\n";
    }elsif($a == $b and $b == $c){
    print "正三角形($a, $b, $c)\n";
    }elsif($a != $b and $b != $c and $c != $a){
    print "不等辺三角形($a, $b, $c)\n";
    }else{
    print "二等辺三角形($a, $b, $c)\n";
    }
    }

    sub triangle_check{
    my($a, $b, $c) = sort {$a <=> $b}@_;
    return ($c > 0 ? ($a > $c -$b ? 0: 1) : 1);
    }
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    しかしこれでも日曜プログラミングの範疇です

    というか入力される整数の最大絶対値を十分に小さく抑えてくれないことには
    仕様を完全に満たせるプログラムは存在しないので…
    1, 2^(10^100)-1, 2^(10^100)-2 などの発狂した値を入力されようとした日には…ねえ
  • id:ita
    しまったそういう引っ掛けでしたか。

    正三角形は二等辺三角形の部分集合か、という
    教科書の論争の話かと思いました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません