【COBOL 書き1-12-14】手も使ってついに中央値算出コード完成〜感動の書きシリーズ1完結

🧩今日の学び
・奇数件の中央値では、件数を2で割った商をそのまま位置にすると1つ手前にずれるため、余りがある場合はLOW-POS1を加える必要がある。
5 ÷ 2のような簡単な例を手で計算し、商・余り・LOW-POSHIGH-POSを表にすると、コードだけでは見えにくい規則やミスを発見しやすい。
・「動きそう」「考え方は合っている」で終わらせず、偶数・奇数など条件を変えて実行し、結果を目で確認するところまでがプログラム設計と検証の一部になる。

なるお)んー、とりあえず…

係長)わかったか?

な)パンケーキ食ってきていいす?

係)なんで「行ってこい!」っていうと思ってるんだよ!!

な)えー、ねっとりシロップを食べることで、甘いという欲求と食べたいという欲求を同時に満たせるんですよ!

係)だからなんで「食べに行って良し」になるんだよ!

いいから、さっさと考えろよ!

な)むー

目次

奇数のときだけ中央値が1つずれている

な)偶数は正解で、奇数が間違ってたんだから…そこら辺かな?

だから、そこら辺ってどこなのよ…と

💻 ターミナル出力 実行結果
COUNT=05 LOW-POS=02 HIGH-POS=02
MEDIAN IS 00900.0

COUNT = 5だからそれはOKで、両POS02じゃなくて03になるはずだから、ここになるのかしら

📝 COBOL 偶数か奇数か判別(ミス版)
           DIVIDE COUNT-LOOPING BY 2 GIVING LOW-POS
               REMAINDER REMAIND.
           IF REMAIND = 0
               COMPUTE HIGH-POS = LOW-POS + 1
           ELSE
               COMPUTE HIGH-POS = LOW-POS
           END-IF.

COUNTが偶数のときはこうだから

           IF REMAIND = 0
               COMPUTE HIGH-POS = LOW-POS + 1

偶数は+1するのはいいでしょー

奇数のときはこうだっつーんだから

       ELSE
           COMPUTE HIGH-POS = LOW-POS

同じで良いわけでしょう??

なんで、一つ少なくなったわけなのかしら…

係)お前偶数と奇数の違いは理解したから、その考えになってるんだよな?

な)あ、あい…

割り切れない計算は頭の中だけで考えない

係)考え方は理解した、それを頭の中だけで計算してるのか?

切り捨てが絡む割り算は暗算に向かないぞ。

な)ほ?

係)偶数はど真ん中の前後の平均、奇数はど真ん中そのものだが、割り切れないだろ?

だったら、どうなるんだ?

な)え…と…

係)だから、頭の中で考えるな、手を使って計算してみろ。

な)あい…

5÷2の商は2だから奇数では1を戻す

な)んー、カウントが5だとして、半分のところになるわけだから、3だよね…

1 2 [3] 4 5

これを出すには52で割るんでしょ??

あれ?

んーと、割り切れないんってことだからして?

うーん…そっか!

5 / 22.5だから、商が21足りないわけだから、LOW-POS1足すと割り切れて、それがそのまま中央値のカウント数字になるからして、これでどうだっての、これで!

📝 COBOL 偶数か奇数か判別(正解)
           DIVIDE COUNT-LOOPING BY 2 GIVING LOW-POS
               REMAINDER REMAIND.
           IF REMAIND = 0
               COMPUTE HIGH-POS = LOW-POS + 1
           ELSE
               ADD 1 TO LOW-POS         ← 追加
               COMPUTE HIGH-POS = LOW-POS
           END-IF.

つまり、割り切れないから、商としては1つ少なくなっちゃうと。

だから、それを戻してあげないといけないってわけっすね!

係)そうだ。

良いか、1 + 1といった足し算ぐらいなら暗算でも間違えることは少ないが、割り算とくに、余りが出るといったときの処理は生活で使うわけでもないからな、あまり使ってこない。

表にすれば偶数・奇数の規則が見えてくる

係)お前ならめんどくさいとか思うだろうが、こういうときは、頭の中で暗算するんじゃなく、表に起こしてしまえ。

今回であればこういう形だな。

件数LOWHIGH
10111
21012
31122
42023
52133
63034

間違いだと気づかずに進めてしまうと、何が間違いだったのかは気が付きづらい。

そうなると、どこにその部分があるかが探しづらい。

単純なミスほど早い段階で目で確認する

だから最初の段階で単純なミスを絶対に犯さないように、めんどくさがらずに、きちんと目で確認しろ。

くだらないミスで泣きをみるのはお前自身だからな。俺は知らんからな。

な)あい…

係)よし、それじゃ、そこ直して実行してみろ。

な)あい…

📝 COBOL 正解コード
       IDENTIFICATION DIVISION.
       PROGRAM-ID. NARUO.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT INPUT-FILE
               ASSIGN TO "naruo2.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT SORT-FILE
               ASSIGN TO "sortwork.tmp".
           SELECT OUTPUT-FILE
               ASSIGN TO "naruo2_sorted.txt"
               ORGANIZATION IS LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD INPUT-FILE.
       01 INPUT-RECORD.
          05 INPUT-SALE-DATE PIC X(10).
          05 INPUT-ITEM-NAME PIC X(20).
          05 INPUT-AMOUNT    PIC 9(5).

       SD SORT-FILE.
       01 SORT-RECORD.
          05 SORT-SALE-DATE PIC X(10).
          05 SORT-ITEM-NAME PIC X(20).
          05 SORT-AMOUNT    PIC 9(5).

       FD OUTPUT-FILE.
       01 OUTPUT-RECORD.
          05 OUTPUT-SALE-DATE PIC X(10).
          05 OUTPUT-ITEM-NAME PIC X(20).
          05 OUTPUT-AMOUNT    PIC 9(5).

       WORKING-STORAGE SECTION.
       01 EOF-FLAG      PIC X VALUE "N".
       01 COUNT-LOOPING PIC 9(2) VALUE 0.
       01 READ-COUNT    PIC 9(2) VALUE 0.
       01 REMAIND       PIC 9    VALUE 0.
       01 LOW-POS       PIC 9(2) VALUE 0.
       01 HIGH-POS      PIC 9(2) VALUE 0.
       01 LOW-VAL       PIC 9(5) VALUE 0.
       01 HIGH-VAL      PIC 9(5) VALUE 0.
       01 MEDIAN-VAL    PIC 9(5)V9 VALUE 0.

       PROCEDURE DIVISION.
           SORT SORT-FILE
               ON ASCENDING KEY SORT-AMOUNT
               USING INPUT-FILE
               GIVING OUTPUT-FILE.
           OPEN INPUT OUTPUT-FILE.

           PERFORM UNTIL EOF-FLAG = "Y"
               READ OUTPUT-FILE
                   AT END
                       MOVE "Y" TO EOF-FLAG
                   NOT AT END
                       IF OUTPUT-AMOUNT IS NUMERIC
                           AND OUTPUT-AMOUNT > 0
                           ADD 1 TO COUNT-LOOPING
                       END-IF
               END-READ
           END-PERFORM.
           CLOSE OUTPUT-FILE.

           DIVIDE COUNT-LOOPING BY 2 GIVING LOW-POS
               REMAINDER REMAIND.
           IF REMAIND = 0
               COMPUTE HIGH-POS = LOW-POS + 1
           ELSE
               ADD 1 TO LOW-POS
               COMPUTE HIGH-POS = LOW-POS
           END-IF.

           OPEN INPUT OUTPUT-FILE.
           MOVE "N" TO EOF-FLAG.
           PERFORM UNTIL EOF-FLAG = "Y"
               READ OUTPUT-FILE
                   AT END MOVE "Y" TO EOF-FLAG
                   NOT AT END
                       IF OUTPUT-AMOUNT IS NUMERIC
                           AND OUTPUT-AMOUNT > 0
                           ADD 1 TO READ-COUNT
                           IF READ-COUNT = LOW-POS
                               MOVE OUTPUT-AMOUNT TO LOW-VAL
                           END-IF
                           IF READ-COUNT = HIGH-POS
                               MOVE OUTPUT-AMOUNT TO HIGH-VAL
                           END-IF
                       END-IF
               END-READ
           END-PERFORM.
           CLOSE OUTPUT-FILE.

           COMPUTE MEDIAN-VAL = (LOW-VAL + HIGH-VAL) / 2.
           DISPLAY "COUNT=" COUNT-LOOPING
                   " LOW-POS=" LOW-POS " HIGH-POS=" HIGH-POS.
           DISPLAY "MEDIAN IS " MEDIAN-VAL.
           STOP RUN.
           

奇数でも正しい中央値!ついに完成

どうよ!プリーズ!

💻 ターミナル出力 実行結果
COUNT=05 LOW-POS=03 HIGH-POS=03
MEDIAN IS 01500.0

どうよ!サンキュー!

係)お前の情緒がわからん…

な)できたんじゃないんすか!これ!

おむすび

係)ま、これでいいだろ。ようやく完成だな…ほんと長かった…。

な)こっちのセリフですよ!

係)なんでだよ!

な)でも、あざんした(ペコ

係)な、なんだよ、殊勝だな…気持ち悪い…

な)ひど!いっつもそうっすよ!ふざけてるとかうるさいとか気持ち悪いとか!

そんなのわかってますから、わかってやってますから!残念でしたー!

係)どんなキレかたしてんだよ!

な)今度クーニャンいきますからね!絶対ですよ!

係)わかったよ…。

ま、よくやったよ。

な)え!?褒められた!?え、だれ!?え、なに気持ち悪い!?

係)ふ、ふ、ふざけんな!

(書きシリーズ 第一部完)

係長のワンポイント

計算ロジックは「頭の中で正しそう」では完成じゃない。
本当は、簡単な数字を手で並べて、結果の規則が合っているか確認するところまでが設計だ。
よくある誤解は、割り算の商をそのまま位置として使えると思うことだが、奇数では余りが出るぶん1つずれる。
だから5 ÷ 2のような小さな例を実際に書き、商・余り・LOW・HIGHの関係を表で確認する。
その結果、単純なミスを早い段階で見つけ、後の大きな手戻りを防げる。
COBOLは頭の中だけで組む言語ではなく、手を使って確かめながら正しさを積み上げる言語だ。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

CAPTCHA


目次