LoginSignup
7
3

More than 5 years have passed since last update.

AtCoder に登録したら解くべき精選過去問 10 (9)問をCOBOLで解いてみた

Posted at

はじめに

COBOLを少しかじってみたので
AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~(Qiita)
をCOBOLで解きました。
COBOLがまだよくわかってない汚いコードをとりあえず置いておきます。
初めての記事で書き方が変ですがよろしくお願いします。

謝罪

最初に書かないといけないことがあります。
タイトルに10問と書いていますが、9問しか解けていません。後述します。すいません。

0問目 practice contest A - はじめてのあっとこーだー(Welcome to AtCoder)

文字列を出力するときに文字数に気をつけないといけないことに気づかずにいっぱいWA出しました。一番苦しみました。
入力は1行まるまるみたいなので複数の変数に分割するのに汚い書き方してます。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 INP PIC X(10).
       01 A PIC 9999.
       01 B PIC 9999.
       01 C PIC X(101).
       01 REN PIC 9999.
       01 RE1 PIC 9.
       01 RE2 PIC Z9.
       01 RE3 PIC ZZ9.
       01 RE4 PIC ZZZ9.
       01 temp1 PIC 9999.
       01 temp2 PIC 9999.
       01 N PIC 9999.
       PROCEDURE DIVISION.
       MAIN.
        ACCEPT REN.
        ACCEPT INP.
        PERFORM VARYING temp1 FROM 1 BY 1 UNTIL INP(temp1:1)=SPACE
        END-PERFORM.
        SUBTRACT 1 FROM temp1.
        MOVE INP(1:temp1) TO A.
        ADD 2 TO temp1.
        PERFORM VARYING temp2 FROM temp1 BY 1 UNTIL INP(temp2:1)=SPACE
        END-PERFORM.
        COMPUTE N=temp2 - temp1.
        MOVE INP(temp1:N) TO B.
        ACCEPT C.
        PERFORM VARYING temp2 FROM 1 BY 1 UNTIL C(temp2:1)=SPACE
        END-PERFORM.
        SUBTRACT 1 FROM temp2.
        COMPUTE REN = REN + A.
        COMPUTE REN = REN + B.
        IF REN < 10 THEN
            MOVE REN TO RE1
            DISPLAY RE1 " " C(1:temp2)
        ELSE IF REN < 100 THEN
            MOVE REN TO RE2
            DISPLAY RE2 " " C(1:temp2)
        ELSE IF REN < 1000 THEN
            MOVE REN TO RE3
            DISPLAY RE3 " " C(1:temp2)
        ELSE
            MOVE REN TO RE4
            DISPLAY RE4 " " C(1:temp2)
        END-IF
        STOP RUN.

1問目 ABC086A - Product

COBOLで剰余を出す方法がわからなかったので商から求めました。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 INP PIC X(100).
       01 A PIC 99999.
       01 B PIC 99999.
       01 temp1 PIC 9999.
       01 temp2 PIC 9999.
       01 N PIC 9999.
       PROCEDURE DIVISION.
       MAIN.
        ACCEPT INP.
        PERFORM VARYING temp1 FROM 1 BY 1 UNTIL INP(temp1:1)=SPACE
        END-PERFORM.
        SUBTRACT 1 FROM temp1.
        MOVE INP(1:temp1) TO A.
        ADD 2 TO temp1.
        PERFORM VARYING temp2 FROM temp1 BY 1 UNTIL INP(temp2:1)=SPACE
        END-PERFORM.
        COMPUTE N=temp2 - temp1.
        MOVE INP(temp1:N) TO B.
        COMPUTE A = A * B.
        COMPUTE B = A / 2.
        COMPUTE A = A - B * 2.
        IF A = 0 THEN
            DISPLAY "Even"
        ELSE
            DISPLAY "Odd"
        END-IF.
        STOP RUN.

2問目 ABC081A - Placing Marbles

3文字のなのでPERFORM使わなくてもいいのですが、練習代わりに使いました。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 INP PIC X(100).
       01 A PIC 99999.
       01 B PIC 99999.
       01 temp1 PIC 9999.
       01 temp2 PIC 9999.
       01 N PIC 9999.
       01 RE PIC 9.
       PROCEDURE DIVISION.
       MAIN.
        MOVE 0 TO RE.
        ACCEPT INP.
        PERFORM VARYING N FROM 1 BY 1 UNTIL N = 4
            MOVE INP(N:1) TO A
            IF A = 1 THEN
                ADD 1 TO RE
            END-IF
        END-PERFORM.
        DISPLAY RE.
        STOP RUN.

3問目 ABC081B - Shift only

配列の作り方を学びました。
1行の入力から変数に切り出すのを綺麗にかけてると個人的には思います。
2で割れるかの判定が変です。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 INP PIC X(2000).
       01 A-REC.
        02 A-DATA OCCURS 200 .
            03 A PIC 999999999 .
       01 temp1 PIC 9999.
       01 temp2 PIC 9999.
       01 temp3 PIC 99999.
       01 N PIC 999.
       01 REN PIC ZZZZ9.
       01 RE PIC 99999.
       01 MOD PIC 9.
       01 R PIC 999999999.
       01 S PIC 999.
       01 NOW PIC 9999.
       PROCEDURE DIVISION.
       MAIN.
        MOVE 10000 TO RE.
        ACCEPT N.
        MOVE 1 TO NOW.
        ADD 1 TO N.
        ACCEPT INP.
        PERFORM VARYING S FROM 1 BY 1 UNTIL S = N
            PERFORM VARYING temp1 FROM NOW BY 1 
                UNTIL INP(temp1:1)=SPACE
            END-PERFORM
            COMPUTE temp2 = temp1 - NOW
            MOVE INP(NOW:temp2) TO A(S)
            COMPUTE NOW = temp1 + 1
        END-PERFORM.
        PERFORM VARYING S FROM 1 BY 1 UNTIL S = N
            COMPUTE R = A(S) / 2
            COMPUTE MOD = A(S) - R*2
            PERFORM VARYING temp3 FROM 0 BY 1 UNTIL MOD = 1
                COMPUTE R = A(S) / 2
                COMPUTE MOD = A(S) - R*2
                COMPUTE A(S) = R
            END-PERFORM
            IF temp3 > 0 THEN
                SUBTRACT 1 FROM temp3
            END-IF
            IF temp3 < RE THEN
                MOVE temp3 TO RE
            END-IF
        END-PERFORM.
        MOVE RE TO REN.
        DISPLAY REN.
        STOP RUN.

4問目 ABC087B - Coins

PERFORMを3周回すコードです。
COMPUTE temp1 = S * 500 + T * 100 + U * 50と書いたらInvalid Expressionとエラーが出ました。厳しい…

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 A PIC 99.
       01 B PIC 99.
       01 C PIC 99.
       01 X PIC 99999.
       01 RE PIC 99999.
       01 REN PIC ZZZZ9.
       01 temp1 PIC 99999.
       01 S PIC 99.
       01 T PIC 99.
       01 U PIC 99.
       PROCEDURE DIVISION.
       MAIN.
        ACCEPT A.
        ACCEPT B.
        ACCEPT C.
        ACCEPT X.
        ADD 1 TO A.
        ADD 1 TO B.
        ADD 1 TO C.
        MOVE 0 TO RE.
        PERFORM VARYING S FROM 0 BY 1 UNTIL S = A
            PERFORM VARYING T FROM 0 BY 1 UNTIL T = B
                PERFORM VARYING U FROM 0 BY 1 UNTIL U = C
                    COMPUTE temp1 = S * 500
                    COMPUTE temp1 = temp1 + T * 100
                    COMPUTE temp1 = temp1 + U * 50
                    IF temp1 = X THEN
                        ADD 1 TO RE
                    END-IF
                END-PERFORM
            END-PERFORM
        END-PERFORM.
        MOVE RE TO REN.
        DISPLAY REN.
        STOP RUN.

5問目 ABC083B - Some Sums

各桁の和を求めるのにMOD SECTION.を使ったら便利でした。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 INP PIC X(100).
       01 A PIC 99999999.
       01 B PIC 99999999.
       01 C PIC 9999999999.
       01 REN PIC 9999999999.
       01 RE PIC ZZZZZZZZZZ9.
       01 temp1 PIC 9999999.
       01 temp2 PIC 9999999.
       01 temp3 PIC 9999999.
       01 N PIC 9999999.
       PROCEDURE DIVISION.
       MAIN.
        ACCEPT INP.
        PERFORM VARYING temp1 FROM 1 BY 1 UNTIL INP(temp1:1)=SPACE
        END-PERFORM.
        SUBTRACT 1 FROM temp1.
        MOVE INP(1:temp1) TO A.
        ADD 2 TO temp1.
        PERFORM VARYING temp2 FROM temp1 BY 1 UNTIL INP(temp2:1)=SPACE
        END-PERFORM.
        COMPUTE N=temp2 - temp1.
        MOVE INP(temp1:N) TO B.
        ADD 1 TO temp2.
        PERFORM VARYING temp1 FROM temp2 BY 1 UNTIL INP(temp1:1)=SPACE
        END-PERFORM.
        COMPUTE N=temp1 - temp2.
        MOVE INP(temp2:N) TO C.
        ADD 1 TO A.
        MOVE 0 TO REN.
        PERFORM VARYING N FROM 1 BY 1 UNTIL N = A
            MOVE 0 TO temp1
            MOVE N TO temp2
            PERFORM MOD
            IF temp1 >= B AND temp1 <= C THEN
                ADD N TO REN
            END-IF
        END-PERFORM.
        MOVE REN TO RE.
        DISPLAY RE.
        STOP RUN.

        MOD SECTION.
        PERFORM 5 TIMES
            COMPUTE temp3 = temp2 / 10
            COMPUTE temp1 = temp1 + temp2 - temp3 * 10
            COMPUTE temp2 = temp3
        END-PERFORM.
       EXIT.

6問目 ABC088B - Card Game for Two

速いソートを書く自信がなかったので選択ソートです。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 INP PIC X(11000).
       01 A-REC.
        02 A-DATA OCCURS 100.
         03 A PIC 999.
       01 B PIC 999.
       01 C PIC 999.
       01 D PIC 999.
       01 ALICE PIC 999999.
       01 BOB PIC 999999.
       01 REN PIC 9999999999.
       01 RE PIC ZZZZZZZZZZ9.
       01 temp1 PIC 9999999.
       01 temp2 PIC 9999999.
       01 temp3 PIC 9999999.
       01 NOW PIC 9999999.
       01 N PIC 999.
       01 MAX PIC 999.
       PROCEDURE DIVISION.
       MAIN.
        ACCEPT B.
        ACCEPT INP.
        ADD 1 TO B.
        MOVE 1 TO NOW.
        PERFORM VARYING C FROM 1 BY 1 UNTIL C = B
            PERFORM VARYING temp1 FROM NOW BY 1 
                    UNTIL INP(temp1:1) = SPACE
            END-PERFORM
            COMPUTE N = temp1 - NOW
            MOVE INP(NOW:N) TO A(C)
            COMPUTE NOW = NOW + N + 1
        END-PERFORM.
        PERFORM VARYING C FROM 1 BY 1 UNTIL C = B
            MOVE C TO MAX
            PERFORM VARYING D FROM C BY 1 UNTIL D = B
                IF A(D) > A(MAX) THEN
                    MOVE D TO MAX
                END-IF
            END-PERFORM
            COMPUTE temp1 = A(C)
            COMPUTE A(C) = A(MAX)
            COMPUTE A(MAX) = temp1
        END-PERFORM.
        MOVE 0 TO ALICE.
        MOVE 0 TO BOB.
        PERFORM VARYING C FROM 1 BY 1 UNTIL C >= B
            COMPUTE ALICE = ALICE + A(C)
            ADD 1 TO C
            IF C < B THEN
                COMPUTE BOB = BOB + A(C)
            END-IF
        END-PERFORM.
        COMPUTE REN = ALICE - BOB.
        MOVE REN TO RE.
        DISPLAY RE.
        STOP RUN.

7問目 ABC085B - Kagami Mochi

制約として1<=A(S)<=100があったので値をインデックスにした配列に入れました。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 INP PIC X(11000).
       01 A-REC.
        02 A-DATA OCCURS 100.
         03 A PIC 999.
       01 B PIC 999.
       01 C PIC 999.
       01 D PIC 999.
       01 ALICE PIC 999999.
       01 BOB PIC 999999.
       01 REN PIC 9999999999.
       01 RE PIC ZZZZZZZZZZ9.
       01 temp1 PIC 9999999.
       01 temp2 PIC 9999999.
       01 temp3 PIC 9999999.
       01 NOW PIC 9999999.
       01 N PIC 999.
       01 MAX PIC 999.
       PROCEDURE DIVISION.
       MAIN.
        PERFORM VARYING N FROM 1 BY 1 UNTIL N = 101
            MOVE 0 TO A(N)
        END-PERFORM.
        ACCEPT B.
        ADD 1 TO B.
        PERFORM VARYING N FROM 1 BY 1 UNTIL N = B
            ACCEPT C
            ADD 1 TO A(C)
        END-PERFORM.
        MOVE 0 TO D.
        PERFORM VARYING N FROM 1 BY 1 UNTIL N = 101
            IF A(N) > 000 THEN
                ADD 1 TO D
            END-IF
        END-PERFORM.
        MOVE D TO RE.
        DISPLAY RE.
        STOP RUN.

8問目 ABC085C - Otoshidama

PERFORM2周回せば大丈夫なやつですね。多めに桁数とった変数からゼロサプレスの変数に転記し忘れるとWA。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 INP PIC X(20).
       01 N PIC 9999999.
       01 Y PIC 99999999.
       01 temp1 PIC 999999999.
       01 S PIC 99999999.
       01 T PIC 99999999.
       01 temp2 PIC 99999999.
       01 temp3 PIC 99999999.
       01 RE1 PIC ZZZZZZZ9.
       01 RE2 PIC ZZZZZZZ9.
       01 RE3 PIC ZZZZZZZ9.
       PROCEDURE DIVISION.
       MAIN.
        ACCEPT INP.
        PERFORM VARYING S FROM 1 BY 1 UNTIL INP(S:1)=SPACE
        END-PERFORM.
        SUBTRACT 1 FROM S.
        MOVE INP(1:S) TO N.
        ADD 2 TO S.
        PERFORM VARYING temp1 FROM S BY 1 UNTIL INP(temp1:1)=SPACE
        END-PERFORM.
        COMPUTE temp1 = temp1 - S.
        MOVE INP(S:temp1) TO Y.
        COMPUTE Y = Y / 1000 .
        PERFORM VARYING S FROM 0 BY 1 UNTIL S > N
            COMPUTE temp1 = N - S
            PERFORM VARYING T FROM 0 BY 1 UNTIL T > temp1
                COMPUTE temp2 = temp1 - T
                COMPUTE temp3 = S * 10 + T * 5
                COMPUTE temp3 = temp3 + temp2
                IF temp3 = Y THEN
                    MOVE S TO RE1
                    MOVE T TO RE2
                    MOVE temp2 TO RE3
                    DISPLAY RE1 " " RE2 " " RE3
                    STOP RUN
                END-IF
            END-PERFORM
        END-PERFORM.
        DISPLAY "-1 -1 -1".
        STOP RUN.

9問目 ABC049C - 白昼夢 / Daydream

これが謝罪のところに書いた解けなかった問題です。
というのも調べ切れてないので断言はできないのですが、COBOLに与えられる入力の最大文字数が8191文字みたいで、10000文字くらいを超えるテストケースに通りませんでした。
一応コードだけ上げます。何かしたら通せるのかな…?

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 INP PIC X(110000).
       01 INV PIC X(110000).
       01 NOW PIC 999999.
       01 temp PIC 999999.
       PROCEDURE DIVISION.
       MAIN.
        ACCEPT INP.
        PERFORM VARYING NOW FROM 1 BY 1 UNTIL INP(NOW:1) = SPACE
        END-PERFORM.
        ADD -1 TO NOW.
        MOVE NOW TO temp.
        PERFORM VARYING NOW FROM temp BY -1 UNTIL NOW = 0
      *     DISPLAY NOW
            IF INP(NOW:1) = 'm' THEN
                IF NOW <= 4 THEN
                    DISPLAY "NO"
                    STOP RUN
                END-IF
                SUBTRACT 4 FROM NOW
                IF INP(NOW:5) NOT = "dream" THEN
                    DISPLAY "NO"
                    STOP RUN
                END-IF
            ELSE IF INP(NOW:1) = 'e' THEN
                IF NOW <= 4 THEN
                    DISPLAY "NO"
                    STOP RUN
                END-IF
                SUBTRACT 4 FROM NOW
                IF INP(NOW:5) NOT = "erase" THEN
                    DISPLAY "NO"
                    STOP RUN
                END-IF
            ELSE IF INP(NOW:1) = 'r' THEN
                IF NOW <= 1 THEN
                    DISPLAY "NO"
                    STOP RUN
                END-IF
                SUBTRACT 1 FROM NOW
                IF INP(NOW:1) = 'e' THEN
                    IF NOW <= 1 THEN
                        DISPLAY "NO"
                        STOP RUN
                    END-IF
                    SUBTRACT 1 FROM NOW
                    IF INP(NOW:1) = 'm' THEN
                        IF NOW <= 4 THEN
                            DISPLAY "NO"
                            STOP RUN
                        END-IF
                        SUBTRACT 4 FROM NOW
                    IF INP(NOW:7) NOT = "dreamer" THEN
                            DISPLAY "NO"
                            STOP RUN
                        END-IF
                    ELSE IF INP(NOW:1) = 's'
                        IF NOW <= 3 THEN
                            DISPLAY "NO"
                            STOP RUN
                        END-IF
                        SUBTRACT 3 FROM NOW
                    IF INP(NOW:6) NOT = "eraser" THEN
                            DISPLAY "NO"
                            STOP RUN
                        END-IF
                    END-IF
                ELSE
                    DISPLAY "NO"
                    STOP RUN
                END-IF
            ELSE
                DISPLAY "NO"
                STOP RUN
            END-IF
        END-PERFORM.
        DISPLAY "YES"
        STOP RUN.

10問目 ABC086C - Traveling

偶奇を調べるのに変な書き方をしました。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. test1.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 INP PIC X(100).
       01 A PIC 99999999.
       01 B PIC 99999999.
       01 C PIC 99999999.
       01 temp1 PIC 999999.
       01 temp2 PIC 999999.
       01 temp3 PIC 999999.
       01 temp4 PIC 999999.
       01 N PIC 999999.
       01 S PIC 999999.
       01 T PIC 999999.
       01 NOW1 PIC 999999.
       01 NOW2 PIC 999999.
       01 NOW3 PIC 999999.
       PROCEDURE DIVISION.
       MAIN.
        ACCEPT S.
        PERFORM VARYING T FROM 1 BY 1 UNTIL T > S
            ACCEPT INP
            PERFORM VARYING temp1 FROM 1 
                BY 1 UNTIL INP(temp1:1)=SPACE
            END-PERFORM
            SUBTRACT 1 FROM temp1
            MOVE INP(1:temp1) TO A
            ADD 2 TO temp1
            PERFORM VARYING temp2 FROM temp1 
                BY 1 UNTIL INP(temp2:1)=SPACE
            END-PERFORM
            COMPUTE N=temp2 - temp1
            MOVE INP(temp1:N) TO B
            ADD 1 TO temp2
            PERFORM VARYING temp1 FROM temp2 
                BY 1 UNTIL INP(temp1:1)=SPACE
            END-PERFORM
            COMPUTE N=temp1 - temp2
            MOVE INP(temp2:N) TO C
            COMPUTE temp1 = A - NOW1
            COMPUTE temp2 = B - NOW2
            COMPUTE temp3 = C - NOW3
            COMPUTE temp2 = temp2 + temp3
            IF temp1 < temp2 THEN
                DISPLAY "No"
                STOP RUN
            END-IF
            COMPUTE temp2 = temp1 / 2
            COMPUTE temp1 = temp1 - temp2 * 2
            COMPUTE temp2 = B - NOW2
            COMPUTE temp3 = temp2 / 2 
            COMPUTE temp2 = temp2 - temp3 * 2
            COMPUTE temp3 = C - NOW3
            COMPUTE temp4 = temp3 / 2
            COMPUTE temp3 = temp3 - temp4 * 2
            COMPUTE temp2 = temp2 + temp3
            COMPUTE temp2 = temp2 - 2
            IF temp2 = 2 THEN
                MOVE 0 TO temp2
            END-if
            IF temp1 NOT = temp2 THEN
                DISPLAY "No"
                STOP RUN
            END-IF
            MOVE A TO NOW1
            MOVE B TO NOW2
            MOVE C TO NOW3
        END-PERFORM.
        DISPLAY "Yes"
        STOP RUN.

終わりに

COBOLだと変数の宣言や処理が難しくて苦労しました。
9問目を通せるようになりたいです。

7
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3