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

#はじめに
COBOLを少しかじってみたので
[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～(Qiita)](https://qiita.com/drken/items/fd4e5e3630d0f5859067#5-過去問精選-10-問)
をCOBOLで解きました。
COBOLがまだよくわかってない汚いコードをとりあえず置いておきます。
初めての記事で書き方が変ですがよろしくお願いします。

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

#0問目　[practice contest A - はじめてのあっとこーだー（Welcome to AtCoder）](https://beta.atcoder.jp/contests/practice/tasks/practice_1)
文字列を出力するときに文字数に気をつけないといけないことに気づかずにいっぱいWA出しました。一番苦しみました。
入力は1行まるまるみたいなので複数の変数に分割するのに汚い書き方してます。

``` COBOL
       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](https://beta.atcoder.jp/contests/abc086/tasks/abc086_a)
COBOLで剰余を出す方法がわからなかったので商から求めました。

```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](https://beta.atcoder.jp/contests/abc081/tasks/abc081_a)
3文字のなので```PERFORM```使わなくてもいいのですが、練習代わりに使いました。

```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.
       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](https://beta.atcoder.jp/contests/abc081/tasks/abc081_b)
配列の作り方を学びました。
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](https://beta.atcoder.jp/contests/abc087/tasks/abc087_b)
`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](https://beta.atcoder.jp/contests/abc083/tasks/abc083_b)
各桁の和を求めるのに`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](https://beta.atcoder.jp/contests/abc088/tasks/abc088_b)
速いソートを書く自信がなかったので選択ソートです。

```
       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](https://beta.atcoder.jp/contests/abc085/tasks/abc085_b)
制約として`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](https://beta.atcoder.jp/contests/abc085/tasks/abc085_c)
`PERFORM`2周回せば大丈夫なやつですね。多めに桁数とった変数からゼロサプレスの変数に転記し忘れると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](https://beta.atcoder.jp/contests/abc049/tasks/arc065_a)
これが謝罪のところに書いた解けなかった問題です。
というのも調べ切れてないので断言はできないのですが、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](https://beta.atcoder.jp/contests/abc086/tasks/arc089_a)
偶奇を調べるのに変な書き方をしました。

```
       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問目を通せるようになりたいです。