predicate1=lambda year : (year-1896)%4==0 predicate2=lambda year : year>=1992 and (year-1924)%4==0 predicate3=lambda year : year<1992 and (year-1994)%4==0
要求仕様は要するに ・1896以降4年おき1924からは夏冬同時開催(戦争中止アリ) ・1994以降2年おき夏冬交互開催 でしょ、と読み替えるとこんな実装になった。 #include <stdio.h> int main(void) {
int y;
for (y=1896;y<=1992;y+=4) {
if (y==1916||y==1940||y==1944) {
printf("(%d) cancel\n",y);
オリンピックの開催年数を表示する例題 (スコア:1)
なんかで読んだ例題で「近代オリンピックの開催年数をすべて表示する」というのがあって、与えられる仕様が以下のとおりー。
・夏季オリンピックは1896年から4年毎で開催
・冬季オリンピックは1924年から4年毎で開催。ただし、1992年の次は1994年から4年毎に開催
・1916年、1940年、1944年は戦争のため開催なし
人によって実装はまちまちだけど、これを誰が見ても分かりやすくメンテナンスしやすいコードを書くにはちょっと経験がいるかも。
模範解答は膝を打った。
まぁ実際の開発の仕事ではもっと複雑だろうけど。
Re:オリンピックの開催年数を表示する例題 (スコア:2, すばらしい洞察)
"http://ja.wikipedia.org/wiki/近代オリンピック"
Re:オリンピックの開催年数を表示する例題 (スコア:1)
Re:オリンピックの開催年数を表示する例題 (スコア:1)
「ただし、1916年、1940年、1944年は除外する」
とか表示しても、それは正解にはならないのですよね、きっと。
¶「だますのなら、最後までだまさなきゃね」/ 罵声に包まれて、君はほほえむ。
Re: (スコア:0)
「近代オリンピックの開催年数をすべて表示する」のが命題なんだから正解ではない。
それが許されるなら、もう箇条書き三行をそのままprintしたらいいじゃんって話になっちゃう。
Re:オリンピックの開催年数を表示する例題 (スコア:1)
「近代オリンピックの開催年数をすべて表示する」のが命題なんだから正解ではない。
というか、一般には、「近代オリンピックの開催年
数のみをすべて表示する」と解釈すべきだろうね。「のみ」でなくていいなら、すべての整数を枚挙する無限ループを書けばいいってことに。
Re:オリンピックの開催年数を表示する例題 (スコア:2)
真っ先に、この方法を思いついたよ:)
大抵は表示するコストが高いから、
「近代オリンピックの開催年数のみをすべて表示する」
ように高速化を狙って、複雑になる、と。
Re:オリンピックの開催年数を表示する例題 (スコア:1)
開催年を単純に計算して表示するプログラムAと
入力から、1916 と 1940 と 1944 以外のデータだけ出力するプログラムBを
パイプでつなぐ。
とか、
開催年を単純に計算して表示したあと、画面(あるのか?)を走査して、1916と1940と1944を見つけたら消す。
ああ、「なかったことにする」処理は難しい。
¶「だますのなら、最後までだまさなきゃね」/ 罵声に包まれて、君はほほえむ。
Re: (スコア:0)
配列に全部用意して除外年は後でペケにするのがいいのでは。
Re: (スコア:0)
私なら過去分をテーブル化しますが、
模範解答はどういうやり方だったんですかね。
・指定した期間(未来可)の間に開催された(る)年を出力しろという指定なのか、過去全て出力するだけなのか。
・夏季と冬季は分けて出力する必要があるのか
このへんがわからないとなんとも。
Re: (スコア:0)
同じく。
今後の開催見通しをはかる部分は単純式で構わないとは思う。
Re: (スコア:0)
私もDBのテーブルで持たせますね。
この手のものは開催年だけではなく開催地とか参加国とか成績とか、そういうのも一緒に
なる事が多いでしょうし、今後も例外年が出てこない保証がどこにもない…。
Re: (スコア:0)
私だったら、例外年のテーブルを作るかな。
Re: (スコア:0)
俺も俺も。
親のコメントの言う『模範解答』がどんなものかわからないけど、
その『模範解答』は模範解答でもなんでもないと思う。
Re: (スコア:0)
どういう文脈で問われているのかわからないので何とも言えないが、特殊な事情がなければ仕様をそのまま書き下す以外にはちょっと考えられない
夏季と冬季を遅延リストにして戦争でフィルターしてマージすれば間違いようもなく、元コメのリクエストにもそのまま対応できるし
テーブル派は二年ごとにプログラムを書きかえるわけ?
Re: (スコア:0)
bool isOpen(year) {
switch (year) {
case 1916:
case 1940:
case 1944:
return false;
break;
de
Re: (スコア:0)
開催年を列挙するのに、夏季と冬季で2回表示される年があるのが我慢ならん。
夏期と冬期の開催年をそれぞれ列挙だったら、それでいいんですけど。
Re: (スコア:0)
これは、釣りだよ。さもなきゃ、
wasHeldをわざわざisOpenにしたりはしないよね〜
Re: (スコア:0)
miyuriさん(#2413780)やasano_nagiさん(#2413787)の意見に賛成です。
無限リストから開催年だけ条件で拾ってくるのが手っ取り早いと思います。
マジックナンバーだらけですが。
#! /usr/bin/env python
import itertools
predicate1=lambda year : (year-1896)%4==0
predicate2=lambda year : year>=1992 and (year-1924)%4==0
predicate3=lambda year : year<1992 and (year-1994)%4==0
predicate_list=[predicate1, predicate2, predicate3]
def main() :
for year in itertools.count(1896) :
Re: (スコア:0)
Re: (スコア:0)
Re: (スコア:0)
下手に無駄なく生成するアルゴリズムよりも、
全ての年について条件に当てはまるか否か判定・抽出するアルゴリズムの方が、
一見バカっぽく見えても、仕様をコードに落としこむ際のエラーは少なそうに思える。
Re:オリンピックの開催年数を表示する例題 (スコア:1)
> 誰が見ても分かりやすくメンテナンスしやすいコード
なので、
以下の考え方が良いような気がします。後々、使い回しも出来そうですし。
> 下手に無駄なく生成するアルゴリズムよりも、
> 全ての年について条件に当てはまるか否か判定・抽出するアルゴリズムの方が、
> 一見バカっぽく見えても、仕様をコードに落としこむ際のエラーは少なそうに思える。
したがって、以下の様な何の変哲も無いプログラムになります。
効率が犠牲になりますが、この程度なら、大した問題にならないでしょう。
# ラムダ式を使えば、もう少しエレガントになりますか?
static void Main()
{
var orympicYears = new List<Int32>();
for( Int32 year=1896; year<=2013; year++ )
{
if ( JudgeIsOrympicYear( year ) )
{
orympicYears.Add( year );
}
}
}
Boolean JudgeIsOrympicYear( Int32 year )
{
// 1896年未満はそもそもオリンピックは存在しないので除外。
if ( year < 1896 ){
return false; // No Orympic Year ( Not Exist )
}
// 戦争による非開催年は除外。
switch ( year ) {
case 1916:
case 1940:
case 1944:
return false; // No Orympic Year ( By War )
}
// 夏季は1896年より4年おきの開催。
{
Int32 tmp = year - 1896;
if ( ( tmp >= 0 ) && ( tmp % 4 == 0 ) ){
return true; // Orympic Year ( Summer )
}
}
// 冬季は、1992年以前は、1924年より4年おきの開催。
// 以後は、1994年より4年おきの開催。
{
Int32 tmp = year - ( year <= 1992 ) ? 1924 : 1994;
if ( ( tmp >= 0 ) && ( tmp % 4 == 0 ) ){
return true; // Orympic Year ( Winter )
}
}
// 夏季も冬季も非開催ならば、除外。
return false; // No Orympic Year
}
Re: (スコア:0)
辞書とかハッシュ使っていいなら
map{ $H{$_}=1 if($_ % 4 == 0) } ( 1896 .. 2013 );
delete $H{1916}
map{print}~
みたいなどうにでもなる話に見えるけど、配列は使用禁止とかそのレベルの縛りがあるんだろうな
Re: (スコア:0)
膝を打った程の模範解答についてもう少し詳しく
Re: (スコア:0)
要求仕様は要するに
・1896以降4年おき1924からは夏冬同時開催(戦争中止アリ)
・1994以降2年おき夏冬交互開催
でしょ、と読み替えるとこんな実装になった。
#include <stdio.h>
int main(void)
{
int y;
for (y=1896;y<=1992;y+=4) {
if (y==1916||y==1940||y==1944) {
printf("(%d) cancel\n",y);