プレイ日記
nobu divine-creator
これはネットで見つけた閏年の判定方法をプチコン式にアレンジしたものなのですけど、これで問題ありませんか? 西暦から計算で28か29を出すことで、閏年かを判定するという式なのですけど、この式の仕組みを正しく理解していませんので、大丈夫なのか分かりません…。
10そうだね
プレイ済み
返信[1]
親投稿
nobu divine-creator
このように年表示はしないのですけど、月が変わる頃に起動すると、日本が3月1日で、ヨーロッパやアメリカは2月末日となる場合に、28日となるか29日となるかで違ってきてしまうため、閏年の判定が必要になりました!
0そうだね
プレイ済み
返信[2]
親投稿
面白い式ですね。 ただ、プチコンの場合は +1) の後ろに >>0 を付ける必要があると思います。 (プチコンでは整数/整数が小数になることがあるため)
0そうだね
プレイ済み
返信[3]
親投稿
この書き方はJAVA系かな? プチコンだとシンプルに N=28+!(DY MOD 4)&&!!(DY MOD 100)||!(DY MOD 400) でOKだと思います。意味的にほぼ同じです。
1そうだね
プレイ済み
返信[4]
親投稿
(あっ。4行目でFLOOR()してるから>>0要らないのか) ボク的にうるう年の判定は IF DY MOD 400==0 THEN N=29 ELSEIF DY MOD 100==0 THEN N=28 ELSEIF DY MOD 4==0 THEN N=29 ENDIF が一番好きですね。
0そうだね
プレイ済み
返信[5]
親投稿
nobu divine-creator
基本的には 4 で割り切れる年…だが、100 で割り切れるとダメ…だけど、400 で割り切れるなら閏年…という条件なんですよね? その条件はだいたい理解しているのですけど、それをたった一行にまとめる式は理解不十分で、小数が出たため FLOOR で補正するという方式にアレンジしました!(その部分は私が自分で考えたものです。) とりあえず、教えてくれた形式に変更しようと思います♪ (なるべく短い判定式にしたいと思うので、上の例のほうで…。)
0そうだね
プレイ済み
返信[6]
親投稿
nobu divine-creator
上の式で2017年を調べると、28でも29でもなくN=0となりました…! 下の式でも2017年はN=0となりましたが、「閏年でない平年は0または28となる」と判断すれば良いってことですか?
0そうだね
プレイ済み
返信[7]
親投稿
nobu divine-creator
ああ!そうか♪ 最初に N=28 を代入しておいて、閏年の場合だけ N=29 になるとすれば良いのか…。
1そうだね
プレイ済み
返信[8]
親投稿
TERA(LL) tera0413
(全く別の発想で) プチコンの場合、DTREADで曜日まで得られるので、2/28と3/1で曜日が連続しているかで、判定する方法も。 エラートラップできれば、もうちょっと簡単になりそうなんだけど・・・ (無い年の2/29の曜日を得ようとするとエラー)
1そうだね
プレイ済み
返信[9]
親投稿
深夜で寝ぼけてたのでELSE忘れてました。
0そうだね
プレイ済み
返信[10]
親投稿
N=28+!(DY MOD 4)&&!!(DY MOD 100)||!(DY MOD 400) も間違えていました。 正しくは N=28+(!(DY MOD 4)&&!!(DY MOD 100)||!(DY MOD 400)) です。 ちなみに &&と*は似たような意味を持つことがあるので N=28+!(DY MOD 4)*!!(DY MOD 100)+!(DY MOD 400) と書くことが出来ます。
2そうだね
プレイ済み
返信[11]
親投稿
Godot orz_127
閏年は400で割り切れれば閏年確定。 そうでない場合は 4で割りきれて100で割りきれないなら閏年。 でよかったかと。
1そうだね
プレイ済み
返信[12]
親投稿
Godot orz_127
DEF 閏年チェック(年)  IF (年 MOD 400) == 0 THEN RETURN 閏年  IF (年 MOD 100) == 0 THEN RETURN 平年  IF (年 MOD 4) == 0 THEN RETURN 閏年  RETURN 平年 END でも良いかと。
1そうだね
プレイ済み
返信[13]
親投稿
nobu divine-creator
な…なんじゃそりゃ~!(吐血) まさか、そのような判定方法があるとは…。 確かに、曜日の順番は固定で、「1つ飛んでいたら29日があることに…」という理屈は分かりますけど、何か遠回りしているような…? 未来の曜日を特定する計算式があるというのは聞いたことがありますけど、それを閏年の判定に使うとは…。 残念ながら、あまり使いたくない方法ですね…。(私には難しいので…。)
0そうだね
プレイ済み
返信[14]
親投稿
nobu divine-creator
基本的には、こういちさんがオススメの方法が良いですね♪(数行かかってしまいますけど、私でも理解しやすいので…。) Godotさんが書かれた方法も似ていますが、判定後の数値が 28 か 29 になるという形式が都合が良いため、今回はそちらの式を使うようにします。 ちなみに、一行で表したいという人は、別式の 1 か 2 を使えば良いと思います。
0そうだね
プレイ済み
返信[15]
親投稿
nobu divine-creator
月日の表示形式を変えました♪
0そうだね
プレイ済み
返信[16]
親投稿
Godot orz_127
何かそれっぽいページを見つけました。 2008年頃の記事ででした。 1行で書けるうるう年判別法 n = 28 + (1 / (y % 4 + 1)) * (1 - 1 / (y % 100 + 1)) + (1 / (y % 400 + 1)); 説明を読むとC言語ベースで話している気配。 この方何故こんなにややこしくしているのでしょう? 計算で求めなければならないという縛りがあったのか? 素直に2項演算子を使えば良いのにと。 n = (!(y % 4) && (y % 100)) || !(y % 400) ? 29: 28;
0そうだね
プレイ済み
返信[17]
親投稿
nobu divine-creator
まぁ、私はその仕組みを理解できていないので、どこが変なのかも分かりませんけど、閏年が正しく判定できさえすれば方法は問いません…。
0そうだね
プレイ済み
返信[18]
親投稿
Godot orz_127
解決したようですが 作っていたので一応 添付しておきます。
1そうだね
プレイ済み
返信[19]
親投稿
なんとなく解説 あの式は IF DY MOD 4==0&&DY MOD 100!=0||DY MOD 400==0 THEN N=29 ELSE N=28 ENDIF の短縮形で N=28+(!(DY MOD 4)&&!!(DY MOD 100)||!(DY MOD 400)) を複雑化したような式です。 ちなみに&&や!は言語によっては+や*と型が違うためエラーが出ます。
1そうだね
プレイ済み
返信[20]
親投稿
まず、*と&&,+と||は似たような性質を持ちます。 実際&&は論理積、||は論理和と呼ばれ、論理回路の世界では 1+1と書いて1 オア 1と読み、答えは1だったりします。 あの式もプチコン上では*を&&、+を||に変えても問題なく動くはずです。(言語によってはエラー)
1そうだね
プレイ済み
返信[21]
親投稿
nobu divine-creator
言語によって記号の意味が違ったり、形式が異なったりするというのは、以前から聞いていましたが、プチコン用の式を作るにはSmile BASICの記号や形式を正しく知っていなければならないので、私にはまだまだ難しい領域ですね…。 それ以前に、複雑な計算式が苦手なので、式の短縮を自分で考えるのは不可能な状態デス…orz。
0そうだね
プレイ済み
返信[22]
親投稿
問題の 1 / (y % 4 + 1) の部分ですが、 ここで言う"/"はプチコンの"DIV"に近い意味を持ちます。 というものもプチコン以外の言語では、整数/整数が必ず整数になるからです。 ちなみに"%"は"MOD"と同じ意味です。 DIVは小数が出たときに、絶対値が小さい方に丸められるため、 1 DIV A はAが1のときに1となり、1よりも大きな数では0になります。あの式の場合1より小さな数や小数は考えないため、Aが1のとき1,それ以外では0という結果になります。 y % 4 + 1が1になるのはYが4で割りきれるときのみなので、結果的にy % 4 + 1とy mod 4==0と同じ意味になります。
1そうだね
プレイ済み
返信[23]
親投稿
おちゃめ ochame_nako
閏年判定を短く記述したいのであればN=28+!(DY MOD 4)-!(DY MOD 100)+!(DY MOD 400)なんてどうでしょうか? 閏年に関しては西暦が「4で割り切れる」「100で割り切れる」「400で割り切れる」という3つの条件を考える必要があります。 4で割り切れない、100で割り切れない、400で割り切れない→閏年ではない 4で割り切れる、100で割り切れない、400で割り切れない→閏年 4で割り切れる、100で割り切れる、400で割り切れない→閏年ではない 4で割り切れる、100で割り切れる、400で割り切れる→閏年 実は、3つの条件は独立したものではなく「4で割り切れる数の集合⊃100で割り切れる数の集合⊃400で割り切れる数の集合」という包含関係になっています。 (続く)
0そうだね
プレイ済み
返信[24]
親投稿
おちゃめ ochame_nako
したがって、「4で割り切れない、100で割り切れる」ということはあり得ないためこの4通りの判定が行えれば良いことは分かると思います。 この4つの判定を見ると3つの条件のうち1つの条件もしくは3つの条件を満たせば閏年になり、条件をすべて満たさないもしくは2つ満たした場合には閏年にはならないことも分かると思います。 ここまでくればあとは「3つの条件のうち1つの条件もしくは3つの条件を満たす」というのをいかに簡略化できるかにかかってきます。 4で割り切れるというのはDY MOD 4==0と記述できますが、これは他の方も書いているように!(DY MOD 4)に置き換えることができます。 それと包含関係を考慮した場合にN=28+!(DY MOD 4)-!(DY MOD 100)+!(DY MOD 400)がある年(DY)における2月の日数になるというわけです。 (続く)
0そうだね
プレイ済み
返信[25]
親投稿
おちゃめ ochame_nako
例えば1900年だと「100で割り切れる」という条件を満たすため!(DY MOD 100)の値は1になりますが、それと同時に「4で割り切れる」という条件も満たすため!(DY MOD 4)の値も1になります。したがって、!(DY MOD 4)-!(DY MOD 100)の値は1-1=0でとなり、28+0=28(閏年ではない)となるわけです。 「論理値 OR 論理値」は「論理値+論理値」で代用(短縮化)というのはよく目にしますが「論理値-論理値」というのは「論理値 XOR 論理値」を代用したものと言えます。 とはいえ、内蔵時計から読み出した日付のみを使うのであればN=28+!(DY MOD 4)で1901年から2099年までカバーできるため個人的にはこれでも十分だと思います。
0そうだね
プレイ済み
返信[26]
親投稿
おちゃめ ochame_nako
判定の短縮化で迷ったらまずは想定されるすべての判定を書きだしてみてそれにどのようなパターンがあるのかを見つけることが重要だと思います。 判定のパターンというとじゃんけんの勝敗判定というのがポピュラーかつ顕著で(X-Y+3)MOD 3のような方法で勝・敗・分が判別可能になります。 閏年の判定もこれと同じように4通りの判定をすべて書き出してやればよいしパターンを見つけられなければその通りIFを使って記述すればよいので問題ありません。(今回の場合だと4通りなので苦にならないと思う) 短縮というのはQSP、OSPといった制限付きプログラムでは大きなメリットとなりますが、そうでなければ大きなメリットはなくデメリットにもなります。(自分で理解できないような短縮はバグや仕様変更の際に自力で変更できない)
0そうだね
プレイ済み
返信[27]
親投稿
nobu divine-creator
そういえば、私はとんでもないことに気がついてしまったのかもしれません! DTREADで現在の年月日(曜日)を取得できますけど、それは日本版での設定なので、日本版以外でこのプログラムを使った場合はどうなるのでしょう? 例えば、北米版で使用した場合、DTREADで得られる日付は日本とズレてしまうことが多いのでは? そうだとすると、日本版以外で使えるようにするには、どうしたら良いのでしょう? 今までDTREADなどを使うプログラムをほとんど作っていなかったため、全く気にしていませんでしたが、それぞれの国で違った日付や時間を取得してしまうなら、別の国で使えるようにするには、どのような補正をすれば対応可能になるのでしょうか? ……というか、欧州版の配信国全てに対応させる方法なんてあるのですかね?
0そうだね
プレイ済み
返信[28]
親投稿
Godot orz_127
表示されるのは所謂ローカルタイムというやつです。 UTCというのを調べてみると良いですよ。 日本はUTC+9です。
0そうだね
プレイ済み
返信[29]
親投稿
Godot orz_127
そう言えば昔はGMTだったなと。 調べ直したら…。 それで最近「うるう秒」と言っているのかと納得。
0そうだね
プレイ済み
返信[30]
親投稿
TERA(LL) tera0413
多分ですが、DATE$とかDTREAD(省略時)って、そこで動いてる3DS本体の現在時刻を読み取っているだけなので、日本版も海外版も得られる時刻は変わらない(現地の現在時刻)と思います。 なので、補正をかけるとしたら、(プログラムを)どこの国で起動したか?を最初に確認して、そこの国を基準にして時差を加減算すれば良いと思います。 (システム変数にリージョンコードみたいなのが有るなら、それを使えば自動でできそうですが・・・)
0そうだね
プレイ済み
返信[31]
親投稿
TERA(LL) tera0413
あ、DATE$、DTREADとTIME$,TMREADです。
0そうだね
プレイ済み
返信[32]
親投稿
nobu divine-creator
はい、私が考えたのも同じような方法で…、まず最初に現在いる国を選択してもらい、その後に日本の日時に変換するという方法です。 そうすれば、日本で日時を取得したのと同じになりますから…。 ちなみに、なぜ現在いる国か?と言うと、どこの国の人?という質問では居場所が違う場合があるので、現在いる国という質問にしています♪
0そうだね
プレイ済み
返信[33]
親投稿
Godot orz_127
普通PCではインストール時にタイムゾーン設定としてそれをやっています。 タイムゾーン設定は後からでも可能です。 日本は「アジア>日本>東京」とかになります。
1そうだね
プレイ済み
返信[34]
親投稿
nobu divine-creator
たぶん、上手く補正できたみたいです♪ 実際に、海外で使った人が正しく表示されたか確認できるまでは、まだ本当に大丈夫か分かりませんけど、とりあえず理論上は合っているはずです…きっと…たぶん…おそらく…。
0そうだね
プレイ済み
返信[35]
親投稿
nobu divine-creator
一応、日本を選んだ場合は正しく表示されています。(補正が入らないからとも言えますけど、以前とはその後の仕組みが変わっているので、修正中は間違えていたのです。)
0そうだね
プレイ済み
返信[36]
親投稿
Godot orz_127
いまいち何をしたいのか判りませんが 3DSの時間設定が日本時間の場合 日本の現在時刻は補正無しの現在時刻 ロンドンの時間は現在時刻-8時間 3DSの時間設定がロンドン時間なら 日本の現在時刻は現在時刻+8時間 ロンドンの現在時刻は補正無しの現在時刻 ※外国の場合サマータイムというのがあるのでちょっと面倒。 テストなら3DSの時間設定を対象地域にあわせればできる筈です。
0そうだね
プレイ済み
返信[37]
親投稿
nobu divine-creator
3DSの時間を変更すると、「毎日ログインボーナスがもらえるようなソフトに悪影響が発生する」のをご存じないのでしょうか? なので、エラーで時間が初期化された場合でもない限りは、3DSの時間を手動で変えるわけにはいかないのです!
0そうだね
プレイ済み
返信[38]
親投稿
Godot orz_127
ご存じないです。 プチコンしかやっていないので特に影響はないです。
0そうだね
プレイ済み
返信[39]
親投稿
nobu divine-creator
うぐぅ……プチコン専用では悪影響ないですね…。 でも、私は困るので、時間を勝手に変えるという方法は選べません…。
0そうだね
プレイ済み
返信[40]
親投稿
ラスコメー 影響出る派です。 確かにプチコンで「時間を操作したらゴールド会員取り消し」とかだったら……恐ろしいです。
0そうだね
プレイ済み
返信[41]
親投稿
nobu divine-creator
そういえば、ゴールド会員の残り日数って、サーバー側が管理していて3DSの日時を変更しても日数が増えるわけではないのかな?(そんなことをする気は無いけど…。) ちなみに、3DSの日時を変更すると悪影響が出るソフトは、そういう不正をさせないための措置らしいですね!
0そうだね
プレイ済み
返信[42]
親投稿
Godot orz_127
普通サーバーにアクセスしては、 ユーザーのアカウントに紐づけてサーバー側で管理されます。 アクセス時にNNIDか何かのユーザーの識別情報が送られ、こいつ金会員か?まだ有効期間か?がサーバー側の管理情報からチェックされ、OKなら、良しお前は金だ、と言うフラグが立ち、特別にこの機能を使わせてやる、という流れになるのかと。
1そうだね
プレイ済み
返信[43]
親投稿
TERA(LL) tera0413
(良しお前は金だ の金がゴールドでなくマネーに読めてふいたw)
0そうだね
プレイ済み
返信[44]
親投稿
nobu divine-creator
Godotさんの解説だと、サーバーが擬人化されてて面白いですね♪ あまりにも人間的過ぎて、メチャ笑えます!
0そうだね
プレイ済み
返信[45]
親投稿
今更ですが、最初の式だと401年などでもうるう年と判定されてしまいます。
0そうだね
プレイ済み
返信[46]
親投稿
Cで実行してみたら401年は大丈夫でした。 ただ、2100年を超えたあたりから正常に判定できないみたいです。
0そうだね
プレイ済み
返信[47]
親投稿
nobu divine-creator
何かそのようなコメントを書いていた人もいたようなので、投稿してみたんですよね…。 やっぱり、欠陥のある式みたいですね。 後からこの投稿を見た人は、最初の式を使わないように注意してください!
0そうだね
プレイ済み
返信[48]
親投稿
安心してください。履いて・・・じゃなかった。/をDIVに変えればすべて解決しますよ。 うまく動かない原因は整数/整数が整数にならないのが原因なので。
0そうだね
プレイ済み
返信[49]
親投稿
nobu divine-creator
なるほど!穿いていなかったのが問題だったのか?!(←間違い) 解決法が分かって安心しました♪
0そうだね
プレイ済み
返信[50]
親投稿
安心してください。 着てますよ。 ……やってみたかっただけです。
0そうだね
プレイ済み
返信[51]
親投稿
nobu divine-creator
確かに、中身が裸でも宇宙服を着ていればセーフですけど、たぶん裸で宇宙服を着るのは問題があるはず…!(・ω・)ノ
0そうだね
プレイ済み
返信[52]
親投稿
おちゃめ ochame_nako
裸コート(ただし、ピンクのぱんつを着用)とどちらがマシですか?
0そうだね
プレイ済み
返信[53]
親投稿
nobu divine-creator
mohさんだったら、果たしてどちらがマシだと判断するのでしょうかね…? ぱんつを穿いている分だけ、コートのほうがマシな気もしますけど…(´-ω-`)。
0そうだね
プレイ済み
返信[54]
親投稿
nobuさん 動きや角度によって「全裸に見える」だけですよ。
0そうだね
プレイ済み
返信[55]
親投稿
nobu divine-creator
じゃあ、ハカセはピンクのぱんつを穿いているんですね!(色は不明…っていうか、知る必要がない!w)
0そうだね
プレイ済み