はじめてのyukicoder vol.5

Fortranのコーディングにも少しばかり慣れてきた、今日この頃

最近思ったのが、Fortranとpython3が少し似てるということ

つまり、構文をちょいちょい書き換えればpython3になる＝python3をタグに入れてもいいのでは？

そんな感じで今日も血さまよってる私です

今日はNo.143,56,5,63,481,47について解きまーす

##No.143
```143.f90
implicit none
integer(8) A,B,f,i,k,m,n
integer(8),allocatable :: x(:)
read(*,*) k,n,f
allocate (x(f))
read(*,*) (x(m),m=1,f)
A=0
do m=1,f
   A=A+x(m)
end do
B=k*n-A
if (B>=0) then
    write(*,*) B
else
    write(*,*) "-1"
end if
end
``` 
思いのほか強敵でしたね・・・

やっていることは単純で、何も特筆すべきことはないです

・食べられる豆の総数を計算
・全体の総数と比較

これだけです

何が一体強敵だったかというと、単純に食べられない可能性を無視していました

"-1"とかあるけど無視しよ、で無視して痛いしっぺ返しをくらいました。

あとは"0"の場合の考慮をしていないとかでしたね

##No.56
```56.f90
implicit none
real(8) d,p,s
integer(8) e
read(*,*) d,p
s=(p/100.0)*d
e=d+s
write(*,*) e
end
```
これは特に言うことはないです。

せいぜいFortranの仕様で消費税16％で25円の税込価格を出そうとしたところ、

28.9999996 だったかが出て上手く表示されなかったくらいです

言語ごとの計算による特徴が見れそうで非常に面白い問題でした

##No.5
```5.f90
program math_block
implicit none
integer(8) A,i,l,m,n
real(8),allocatable :: x(:)
read(*,*) l
read(*,*) n
allocate (x(n))
read(*,*) (x(m),m=1,n)
call mat(x,n)
A=0
do i=1,n
   A=A+x(i)
   if (A>l) exit
end do
write(*,*) (i-1)
end program

subroutine mat(x,n)
integer(8) n,j,i,t
real(8),dimension(n) ::x
  do i=1,n-1
     do j=i+1,n
        if(x(i) > x(j))then
           t=x(i)
           x(i)=x(j)
           x(j)=t
        end if
     end do
  end do
end subroutine
```
これも特に言うことはないです

数字を配列に格納して、幅を超えるまで小さい順に足し合わせた

この一行で説明できます

立方体に隙間なく並べるとかになると非常に面倒そうですね

美しさの欠片もないので、簡潔なコードを書きたいです

##No.63
```63.f90
implicit none
integer(8) L,K,Y,C
read(*,*) L,K
C=L/K
if (mod(L,K)==0) then
   if (mod(C,2)==0) then
       Y=(L/2)-K !(1)
       write(*,*) Y
   else
       Y=(C/2)*K
       write(*,*) Y
   end if
else
   Y=(C/2)*K
   write(*,*) Y
end if
end
```
場合分けが面倒でした

手順として、

・ポッキーの全長が齧る長さで割り切れるで場合分け

これは割り切れなければ、(L/K)/2回齧った所で絶対に触れることはないからです

と言葉でいちいち説明すると分かりにくいので、

みなさまのためにぃー、このようなぁー、図を用意しましたぁー

![ぽっきー.png](https://qiita-image-store.s3.amazonaws.com/0/293790/8fca56fe-cc3b-15dc-7c5b-fa14461708a3.png)

この問題の重要なところは、図の青い線の長さです

この長さがK以下ならば絶対に唇が触れ合うので、それまでの齧る回数にKをかければ答えになります

で、何が一番面倒なのかと言うと、青い線が零の場合です

その場合、齧る回数から一回分だけ引かなければなりません

それを数式で示すと　((L/K)/2－1)*K となり、整理したものが!(1)です

<br>

と論理的に解説すると単純な問題なのですが、いざやるとなると頭がパニックを起こしました

この問題を作った人は絶対許早苗　(八つ当たり)

##No.481
```481.f90
implicit none
integer(8) A,i,m
integer(8),allocatable :: x(:)
allocate (x(9))
read(*,*) (x(m),m=1,9)
do i=1,10
   if (x(i)/=i) then
       write(*,*) i
       exit
   end if
end do
end
```
特に言うことはないです

数字を配列に突っ込んで、それぞれをループ文で順に参照して、一致しない数字を表示

これだけ

##No.47
```47.f90
implicit none
integer(8) A,n,s
read(*,*) A
n=1
s=0
do while(A>n)
   n=2*n
   s=s+1
end do
s=s-1
if (n==A) then
    write(*,*) s+1
else
    n=(n/2)
    if (mod(n,2)==0) then
       write(*,*) s+1
    else
       write(*,*) s+2
    end if
end if
end
```
ここまで丁寧にやる方がいいのかなぁーとか思いながら書きました

最初はこんなのどうやって解けって言うの？とか思っていましたが、冷静に考えると単純でした

考えるポイントは奇数の作り方です

・偶数 ＋ 偶数 ＝ 偶数
・偶数 ＋ 奇数 ＝ 奇数
・奇数 ＋ 奇数 ＝ 偶数

という今日日、算数で学ぶ例のアレ

奇数枚を要求されたとき、偶数に何かしらの奇数を足さなければなりません

ここで普通ならどういった奇数を足すのかで頭を悩ませる所ですが、

この問題で作り出せる奇数は決まっています

"1"だけしか存在しえないのです

というわけで、結果的に奇数の場合は偶数に比べて1回多くなるよネ

とても楽しい問題でした
<br><br>


もうすぐ初心者のためのガイドで示されている簡単な問題を解こう、が終わります

これを乗り越えると、アルゴリズム的な、簡単に言うとパターン的な問題がメインとなるようです

所謂、競プロ山の一合目でしょうか？

んー、本格的にアルゴリズムの勉強をするべきなのか、

自分で数式を組み立ててプログラミングをする方がいいのか、非常に迷うところです

それから、実績的な何某が欲しいのでアプリ開発に着手でもしようかなーとも考えています

何をするにしても、Qiitaで発信できたらと考えています

以上！