■
このブログの目的
プログラミングの勉強には実際に描くこと、技術系記事を書いて他人に残すことなどが良いとqiitaで読んだので、単純な思考回路を持っている私は
『つまりhtmlで技術系ブログを書けば一石二鳥ってことですね!!!』
などと考えました。つまりそういうことです。
また、qiitaを選ばない理由については単純に技術者の集まるクソコードをアップするのが怖かったので。
>まずは筆者の環境など
環境
- MacBook Pro 13インチ,2017 ※ローン返済中
- VScode+Vim ※死ぬほどググりました。1~2週間くらいかかった。
- プロセッサ 3.1Ghz Intel Core i5
- メモリ8GB 2133Mhz
この辺とりあえず『このMacについて』の項目を丸写ししてます。敢えて付け加えるならLinuxやりたいけどVirtualBox重いのとキーボード変更が面倒…
知っている言語
- Progateで最後まで進めたのはRuby
- とりあえず入門書を読んだC言語
- AtcoderのTutorialで覚えたC++
- その他Progateでの無課金の範囲一通り
- 現在この記事をググりながら書いています
課金したのが最近なのでRuby以外はまだ進めていないです。
なんかRails on Tutorialやっとけ!みたいな記事が多いのでとりあえずRubyだけ。
プログラミングの経験など
- 理工系なので大学でCの基礎をやったくらい。文系の人が『初心者じゃないのかよ!騙された!』と言ってきそうな未来が見えたので自己弁護をしておくと、大学で習うプログラミングなんて大体入門書一冊分書かせて満足感を与える作業ですのでAtcoderのチュートリアルができれば追いつけるんじゃないでしょうか。
- 開発経験はなし。無理やりあげるならUnityのチュートリアルやった程度ですがプログラム部分はほぼコピペなのでノーカンかと思われます。
- 数学はまあまあ。少なくとも大学数学を使った記憶がないので恐らくプログラミングで使えるレベルには到達していません。
2つだけじゃ何かもう一つ書こうと思ったのですが思いつきませんでした。多分Progateと、Atcoderのチュートリアルをやればすぐに抜けると思います。
……あのチュートリアル、その辺の入門書やるより良いと思う。
問題振り返り
A / Changing a Character
tolower()が頭から抜け落ちてたので直接32を引きました。
文字コードから32を引くと小文字、足すと大文字になるみたいな感じです。tolower()やtouppper()忘れた時に便利。
#include#include #include #include #include #include #include using namespace std; int main() { int N, K; cin >> N >> K; string S; cin >> S; S[K - 1] = S[K - 1] + 32; cout << S << endl; }
B / YYMM or MMYY
おまたせしました、クソコードの時間です
https://atcoder.jp/contests/abc126/submissions/5473979
#include#include #include #include #include #include #include using namespace std; int main() { int s; cin >> s; int one = s / 1000; int two = (s / 100) % 10; int three = (s / 10) % 10; int four = (s % 10); int front = one * 10 + two; int back = three * 10 + four; if ((0 < front && front <=12) && (12 < back || back==0)) cout << "MMYY" << endl; else if ((0 < back && back <=12) && (12 < front || front==0)) cout << "YYMM" << endl; else if (front==0 || back==0 || (front> 12 && back > 12)) cout << "NA" << endl; else cout << "AMBIGUOUS" << endl; }
落ち着いて見直すとすごいです。 one,two,three,fourは左から1桁目、2桁目……を表しておりfront,backは上位2桁、下位2桁を表し…
いやこれ一つに纏まったよね? 解説文を見れば分かると思うのですが、上位二桁はa/100、下位二桁はa%100で大丈夫です。なぜか1桁1桁求めてますが時間の無駄です。 そしてなぜかAMBIGUOUSを最後に求めてますが、これも解説通りAMBIGUOUSを真っ先に求めるべきだと思います。
例えるならFizzBuzz問題で3の倍数で5の倍数じゃないやつ、5の倍数で3の倍数じゃないやつ…と設定していく感じでしょうか。力技に頼りすぎてる感。
この問題に限らず、集合においてA、B、A∩Bを出力するようなやつが出たらA∩Bから求めていきたい。(流石に一般常識の範囲なので大反省してます、焦ってると忘れちゃうときがあるとはいえ)
C / Dice and Coin
これは失敗例です
https://atcoder.jp/contests/abc126/submissions/5478020
#include#include #include #include #include #include #include using namespace std; int main() { int n, k; // n面サイコロ、kが目標点数 cin >> n >> k; double answer = 0; int point; int count = 0; for (int i = 1; i <= n; i++){ count=0; point=i; while (point <=k) { count +=1; point *=2; } if (i>= k) { answer += 1 / double(n); continue; } answer += (1 / double(n)) * (1 / pow(2.0, count)); } printf("%.12lf\n", answer); }
勝った!AC!第3問完!……2ケース落ちてるぅぅぅうぅ……
…御察しの通りクソコードです
出来の悪さに嘔吐しつつ思考プロセスを追うと、まずは0.5を何回掛けるかをcountに出力してそれからcountの回数分だけ求めます。ただ解説を見れば分かるのですが、countは全く必要ありません。
まあもう汚さは振り返っても仕方ないので、とりあえずここに辿り着く過程を書いてみます。
- よしとりあえずコード書け……あれなんかおかしい(なぜかnをiにしてたり色々)
- とりあえず一通り修正(countとか色々加える)……そういえば答えが整数のまま……!!
- とりあえず答えをdouble型にしておけば正解…あれ!?桁数が足りない(printf部分がcoutになってた)
- 多分coutは桁数指定できないのかな?ならばprintf……あれ、桁数が足りない!?(小数点以下の桁数指定の書き方を忘れる)
- ググったら桁数指定できた……これで勝っあれぇ!?(ぶん投げたら2ケース落ち)
※これは真似をしてはいけない例です。
D~F
初心者ブログなのにこれができたらクレームがくるので敢えてやりませんでし……嘘です普通に時間切れですゆるして叩かないで
反省とまとめ
いや〜、振り返ってみると予想以下の出来でした
流石に通ったし人に見せられるコードだろうと思いきや基礎すらヤバイ……痛感いたしました。
初心者とはいえ流石に色々やったし基礎力くらいは付いているだろうという慢心はいけませんね、そして上位の方々のコードを見ると本当美しい&分かりやすい。少なくとも変な変数とかは一切無いですね、当たり前ですが。
そして何よりまずいのがこうして文字に残すまでは割といけるだろうと考えていた事です。もちろん解説を見たあとは撃沈したのですが。
さて、話は変わりますが今回の目的として反省ともう一つ技術系の記事を書くこととコードを実際に残す事ですがもう上の文章見れば分かるんじゃないかな、と遠い目で言ってみます。
人に残す文章なので自分のコードを解説や他の方と照らし合わせて説明する必要があるのですが、もう出るわ出るわボロの山。すごく、すごく参考になってるので疑いようがないですね……他人の真似をする事はとても大事だって多分数世紀くらい先祖代々伝わってますが正にそんな感じです。
そしてhtmlですが、とりあえず全く分からなかった見出しタグの使い分けやらあんまり覚えてなかったタグの確認には良いですね……などと言ってたらulタグ忘れてましたしpタグで改行する仕様が頭から抜け落ちてました。それにmetaタグについては全く知りませんでした。」はい、つまり有効です。実戦で証明していくソルジャーの鑑。