【人類向け】基本的なテキスト操作のショートカット【キーは3つ】
[人類向け]基本的なテキスト操作のショートカット[キーは3つ]
まえがき
殆どのアプリ、OSで共通なキーボードのショートカットについて纏めてみることにしました。知らない場合は覚えれば爆速になります。
多分検索すれば色々出てきますが、私はプログラムを書くことが多いので今回はテキスト入力に絞っての記事になります。
筆者の環境はmacですがwinキーボードでも入力に関しては大体同じことができたのを確認済みです。
適当なテキストを自分で打って確かめてください。
適当なテキストを自分で打って確かめてください。
とても大事なことなので二回太字で書きました。
結論
結論から言ってしまうと
- shiftキーで選択!!
- optionキーでちょうど良い感じの移動!!
- commandキーで一気に移動!!
こんな感じで覚えておけば大体OKです。
以下の動作はoption,shift,commandから指を離さずに行なってください。
shiftキー
shift+方向キー
移動した範囲が選択される。
以上!!まずは
『shiftキーを押している間は移動した範囲が選択される』
『他のキーと組み合わせて使える』
これだけ覚えておけば多分大丈夫です。
optionキー
optionキー+左右矢印
一単語分の移動
option + delete
一単語分の消去
option + 上下矢印
カーソルが乗っている行を移動(複数行が選択されている場合は選択されている行全て)を上下に移動
…このままだと単語一つ分のカーソル移動が早くなるだけ、deleteやキーの移動が早くなるだけだと思われるのですが、shiftを押している最中にも全く同じ動作ができるというのがポイントです。
つまり、単語一個間違えた時にoptionとshiftと矢印を押すだけで一個分素早く選択できます。なぜ太字で強調したのか……こいつらの真価は次のキーと組み合わせたときにわかります。
commandキー
覚えることが多くなりますがひるまないでください。
人類にとって超使えるコマンドなので頑張って。
ちなみに親切そうに励ましてはいますがコピペについては今更だと思うので解説しません‥‥‥やればわかる、もしくはググって。
command + 左右矢印
行の左端/右端に移動します。
command + 上下
文章の最上段、最下段に移動します。
command + C
コピー、いわゆるコピー&ペーストのコピーです
command + X
カット、コピー+取り消しです。
これもペーストと合わせて使ってください
command + V
ペースト。コピーした文を貼り付けます。
上のコピーやカットと合わせて使ってください
command + A
全選択、文章を全部選択します。
command + Z
取り消し、直前の動作を取り消します。
command + F
検索。テキストと銘打っているので、紹介するか迷いましたが非常に使えるので。
command + G
検索項目の次の出現箇所に向かいます。
前に向かいたいときはshiftを押しながら。
はい、一気に多くなりましたが、これを先ほどのshiftキー,optionキーと組み合わせることで爆速になります。
例えば一行丸々コピ-したいなら、
①command+矢印で一番端に移動。
②shiftを押す
③shiftを押しながら、command+矢印、1行分選択されたのでcommand+c
大体3ステップでいけます(実際にやってみてください)
私事としてはcommand+Aでソースコード全選択したあとに、Cでコピー、VでAtcoderに貼り付けなどということをやったりoptionキーで移動が早くなったりまあ割と色々です。
あとがき
shiftとoptionについて最近知ったのでまとめました。正直知らなかったのはとても悔しいです。
今回書いたこと以外にも沢山のショートカットがありますし、今回の組み合わせでも例えばブラウザでoption+下矢印でいい感じのスクロールなど、様々なものがあります。ぜひ試してみてください。
ですが、紹介していくともう無限にあるのでキリがないですし、多分競技プロ関連の人が多いので一番役立つのはこの知識かなと‥‥‥とりあえずまとめてみました。実際爆速です。
もし知らなかったあなたも、ぜひ楽しい爆速ライフを
ARC034備忘録
ARC034備忘録 初めてのARC
はじめに
バイト疲れのため最初の1時間寝てました、なのでギリギリに書いたコードになります……という言い訳を書いておきます。
A問題
※提出したコードは上記のリンクから辿れます。
先ほどの事情により急いで書いた為少々汚い部分があったので説明の為比較的綺麗なコードに直しました。
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main() {
int n, a, b, c, d;
cin >> n >> a >> b >> c >> d;
char s[n];
// Aがゴールのパターン、Bがゴールのパターン
bool flag = true;
for (int i = 1; i <= n; i++) {
cin >> s[i];
//岩が二連続のパターン
if (i >= a && i <= max(c, d)) {
if (s[i] == '#' && s[i] == s[i - 1]) flag = false;
}
}
// c>dならb動かしてa動かして終わり
if (d < c) {
for (int i = b; i <= d; i++) {
//途中に3つ空きがあればtrue、無ければ追い越せないのでfalse
if (s[i]==s[i + 1] && s[i]==s[i - 1] && s[i]=='.' ) {
flag=true; break;
}else{
flag=false;
}
}
if (flag)
cout << "Yes" << endl;
else
cout << "No" << endl;
return 0;
}
まず、範囲内に岩が二連続である場合は強制的に失敗です。これは入力時に確認できるのでさっさとやっちゃいましょう。
そして、Aの到着地点よりBの到着地点が後ならこれもBを先にゴールさせてAをその後にゴールさせれば良いので終わります。
ここまでは多分良いとして、おそらくつまづくのは追い越しのパターン、つまりD < Cですね。まずは図にして考えます。
a---------b------d---------c (-は岩(#)か道(.)のどちらか)
岩が二連続のパターンは既に判定しているので、調べる範囲はb~dの間であることがわかります。
どういった場合に追い越せなくなるかということを考えると、常に2マス先までBと岩で埋まっている時になります。……逆に言えば、一瞬でもそうじゃない状態があるかどうかを判定すればOKです。
..#...#..#..#..#..#『A B .』#.....#...#..#.
そこで、AとBを動かして考えましょう。注目するのは『』の部分。
こんな感じに、隣接するスペース、B、その次の地面……というスペースが存在する事が追い越せる条件になるので、3連続の空きマスがあるかどうかを判定してみればOKです。
B問題
説明簡略化のため、解説通りにBCをDに置き換えて説明します。
まず,AAAAAAAADみたいなパターンだとAの数だけ変換されます。
次に、AAAADAAADAD……というパターンですが、太文字の部分に注目しましょう。この部分は、DAAAAとなってAの数だけカウントされます。
その操作後には、DAAAAAADADとなるので、二つ目のDは一つ目の『AAAAD』と『AAAD』のAの数の合計が操作回数になります。
つまり、ある一つのDに対しては、その前のAの数を数えればそのDに関わる全ての操作回数になります。あとはこの和を求めていきましょう。
ただし、ここで注意すべきこととして例えば20万文字中にAが10万個、Dが5万個(元がBCなので)の場合50000*100000 > 2*10^9(おおよそint型の範囲) を超えてしまうので、答えの値はlongなど大きい範囲の数値を扱えるものにしておいてください。
まとめ
寝坊という盛大なガバについては言及しません。
とりあえず、競プロを初めて2ヶ月……C++の文法をあまり知らない状態から400点問題が普通に解けるようになったのは嬉しいです。
この前日の企業コンテストでまさかの500点問題……B問題の文を勘違いしてミスり、さらにCの高校数学(後半の条件で?マーク)、D問題には実装についてはまだあまり詳しくない木構造が出て虐殺されたばかりだったので、反動で嬉しくなって更新しました。
今回のB問題も解説を見てある程度まで大体理解できるようになったので、実力はついたと思いたいです……実装力は無いですが。ですので競プロ界隈の巷では有名なプログラミングコンテスト攻略のためのアルゴリズムとデータ構造 (通称:螺旋本)を購入しました。
Atcoderで滝のように浴びるにしても知識が足りずにどうしようも無い物も多く、どうすべきか迷ってたのですが、そもそも基礎が足りて無いのでしばらくはAOJのコースリスト埋めに走るかもしれません。有名なqiita記事のAtcoder版蟻本初級編でもやろうと思ったのですが(超おすすめ記事です)蟻本が図書館から借りたものなので現在家に無いのです、悲しい。
前の記事でAtcoder頑張るって書いた気がするのにAOJに浮気してますがまあそれはいつものことです、うん(同じ競プロなのでセーフ)
■
ABC127 初心者備忘録
A - Ferris Wheel
using namespace std;
int main() {
int a, b;
cin >> a >> b;
if (a >= 13)
cout << b << endl;
else if (a <= 12 && a >= 6)
cout << b / 2 << endl;
else
cout << 0 << endl;
}
普通の条件分岐です。これ以上語ることがないですね……正直A問題って毎回何を語るのか困るので次からカットしたいと思います。楽をしていく。
B - Algae
using namespace std;
int main() {
int r, d, x;
cin >> r >> d >> x;
for (int i = 1; i <= 10; i++) {
x=r * x - d; cout << x << endl;
}
return 0;
}
xにrx-Dを代入、それを表示する感じです。 次に代入する時は一つ前のxが残ってるので結果的に問題文の式
x[i+1]=r*x[i]-D
になります。ちなみにiに入る数値は2001~2010となってますがぶっちゃけ1~10でも変わりません。
N^3したら計算量に関わってきそうな大きい数字が出ても焦らないように注意……私は焦りました。
C - Prison
using namespace std;
int main() {
int N, M;
cin >> N >> M;
int L[M], R[M];
for (int i = 0; i < M; i++) { cin>> L[i] >> R[i];
}
int Lmax = 0, Rmin = N;
for (int i = 0; i < M; i++) {
if (L[i]> Lmax) Lmax = L[i];
if (R[i] < Rmin) Rmin=R[i];
if(Lmax> Rmin){
cout << 0 << endl; return 0;
}
}
if (N < Rmin - Lmax + 1) {
cout << N << endl;
} else if (N>= Rmin - Lmax + 1) {
cout << (Rmin - Lmax + 1) << endl;
}
return 0;
}
要はIDカードの数字が、L(左側)の一番大きい数字からR(右側)の一番小さい数字の間なら通り抜けられます。
それらを求め、引き算でその間に幾つの数字があるかを調べます。ただし右側が左側より小さい数字になったら通り抜けられないので0を表示。
後はNより範囲が多かったらN枚フルに使える、N枚フルに使えないなら範囲の分だけが枚数に、という条件分岐です。
D - Integer Cards
bool compare_by_b(pair<int, long> b, pair<int, long> c) {
if(b.second != c.second){
return c.second < b.second;
}else{
return c.first < b.first;
}
}
int main(){
int N,M; cin>> N >> M;
vector A(N);
vector <pair<int,long> > card(M);
int count =0;
long answer=0;
for(int i=0;i<N;i++) {
cin>> A[i];
}
for(int i=0;i<M;i++) {
int b,c;
cin>> b >> c;
card[i] = make_pair(b,c);
}
sort(A.begin(),A.end());
sort(card.begin(),card.end(),compare_by_b);
for(int i=0;i<N;i++) {
if(A[i]>= card[count].second || count > M) break;
if(card[count].first != 0){
A[i] = card[count].second;
card[count].first--;
}else{
count++;
A[i] = card[count].second;
}
}
for(int i=0;i<N;i++)
answer +=A[i];
}
cout << answer << endl;
}
通ったのは12ケース、つまりACではありません
Aのもっとも小さい数を、Cの最大の整数と置き換える貪欲法です。
簡単に言うとN枚のAと入れ替え用のカードがあり、Aのカードを小さい順、入れ替えカードを大きい順にソートします。
そして、前から順番に見比べAのカードより入れ替え用カードが大きかったら。Aのカードが入れ替えカードの数になります。
ある場所でAの数字が入れ替えカードの数字以上になったら、予めソートしている為以降もそうなります。なので、ループ脱出です。
……とまあこんな感じの考え方だったのですが、8ケース落としました。正直初めてD問題クリアできると思ったのでかなり悔しいです。
しかし12ケース通るということは多分筋道は合っているはずなので、後は見落としてたり考え不足の部分ですね。頑張ります!
まとめ
今回で確信したのですが、もうC問題まではほぼ解けるといってもいいでしょう。しかし、D問題以降はもう別世界です。
大体のD問題は優先探索系、コンテナ、グラフ等本格的にアルゴリズム特有の知識が必要になっていきます。とりあえずアルゴリズムの項目があるので応用情報の本を読んでみたのですが未だに人月という全く役に立たない単位を採用してるだけあってやはりレベルが低競技プログラミングの敷居は少々高いのか全く載ってませんでしたね、というわけで図書館で借りてきました、有名な蟻本をもう一回読んでみます。
はい、難しいです。いや正直今なら全てが理解できるはずという謎の自信をもって挑んだのですがすごいです……密度が濃くて……。
ですが、競技プログラミング本が少ないことや一般的なアルゴリズム本で書かれている内容が初級であること、それに問題の豊富さを考えると初心者向けではありませんが間違いなく名著です。このブログにアフィリエイト機能がついてたら多分貼り付けてました。買いたい方は「蟻本」でググってください。
というわけで、しばらくは螺旋本かチーター本を買って再び勉強です。……おかしいな、今月分の学費の支払いを終えると残金-40k……?
……………………………………なんとかします!!!!
■
ABC050初心者備忘録 Rubyの勉強がC++の役に立った話
三行雑まとめ
- ブログを振り返る!
- 問題を振り返ってみる!
- プログラミングの効果
……といったものになります
ぶっちゃけ前半は前回のブログを書いたことに関する感想文なので、問題などをとっとと見たい方は問題Aの項目まで飛ばしちゃって大丈夫です
初めてブログを書いたことの振り返り
実際にやってみると以外と躓く。そして楽しい!これが結論であり全てです。開発経験は?と聞かれる理由が分かりました。これに関してはうだうだ言うよりも。
初心者の方は何か形に残るものを作ってみよう!
これに尽きます。色々と読んだり動画見ながらコード写経するより大きい経験値が得られると思いました、もちろん最低限の基礎は必要ですが。
そして当ブログに関しては、しばらくはrails on tutorialの進捗と競プロ、後は気になったこと色々の雑記にしようと考えています。ふわふわしてますがよろしくお願いします。
問題A
ヘッダファイル部分は省略します。なんかヘッダファイルの読み込み部分がが消えるので……
using namespace std;
int main() {
string s;
cin >> s;
for (int i = 0; i < s.size(); i++) {
if (s[i] == ',') s[i] = ' ';
}
cout << s << endl;
}
要はsの中身を全部見て'.'の部分を' 'で置換するやつです。語ることもないので次!
問題B
int main() {
int k, s;
cin >> k >> s;
int answer = 0;
for (int i = 0; i <= k; i++) {
for (int j = 0; j <= k; j++) {
if (0 <= s - i - j && s - i - j <= k) answer++;
}
}
cout << answer << endl;
}
過去問精進10選の第8問と同じで、2500^3=(2.5*10^3)^3>10^9であることは簡単に予想できるので計算量を減らす工夫として二重ループの後に比較しましょうというものです。
詳しくは、Atcoderのチュートリアルにも載っている過去問精進10選を参考にしましょう。もしこれが分からなかった方は見直すのがおすすめです
問題C
using namespace std;
void moveR(int x1, int x2) {
for (int i = 0; i < x2 - x1; i++) {
cout << 'R';
}
}
void moveU(int y1, int y2) {
for (int i = 0; i < y2 - y1; i++) {
cout << 'U';
}
}
void moveL(int x1, int x2) {
for (int i = 0; i < x2 - x1; i++) {
cout << 'L';
}
}
void moveD(int y1, int y2) {
for (int i = 0; i < y2 - y1; i++) {
cout << 'D';
}
}
int main() {
int sx, sy, tx, ty;
cin >> sx >> sy >> tx >> ty;
moveR(sx, tx);
moveU(sy, ty);
moveL(sx, tx);
moveD(sy, ty);
cout << 'D';
moveR(sx, tx + 1);
moveU(sy, ty + 1);
cout << 'L' << 'U';
moveL(sx, tx + 1);
moveD(sy, ty + 1);
cout << 'R' << endl;
return 0;
}
はい、お待ちかねのクソコードの時間です
といってもこちらは簡単でstring(文字数,'文字')で初期化出来ることを知らなかったというのが反省点ですね。知識は本当大事、やるたびにいつも思います。
いつもならこのfor文を一つ一つ手書きで描いてるので、相対的に見て成長している…?と自分を甘やかしてみます。
経路についてですが、要は長方形を作るような経路を通った後にその1マス外側を通るというものです。説明に関してはAtcoderの解説を見てもらえれば分かるのですが、いくつかやってみて迷路問題は競プロにおける一種の典型問題であると思ったのでこの周り4マスは必ず通るという考え方は今後度々使われていくと思っています。ちなみに某社のインターンのテストで正にその考えを使う問題に気が付いたけど、リアルの時間がなくてwebテスト途中で実装部分だけ書いたのが最近の後悔です。当たり前ですがwebテストは余裕のある時に受けましょう。
まとめ
まず始めに、問題Cは今まで苦戦だらけだったのでめちゃくちゃあっさり解けたことに驚いています。もちろん難易度の違いもありますが、10分足らずで解けたのは結構珍しいです。
その理由として考えられるのが、Rubyを勉強したことです。
私はdfsや再帰など、ある程度テンプレ化しているもの以外で関数を作るのが極端に苦手だったのですが、ProgateのRubyの講座はオブジェクト指向だったのでどうしても返り値やら受け渡しの概念を理解しないといけません。
ですが、CやC++に比べて非常に分かり易かったために既存の知識と組み合わせるとすらすら解けました。それだけではなく、Rubyの勉強を行うことによって逆にCやC++の理解も深まりました
結論としては、他の勉強を行うことで、自分が詰まっている概念について理解が深まるということは結構あるのではないかという推測ができそうです。少なくとも理工系の授業はそういった側面が多いので……勘ですが。
私自身、まだまだまだまだ初心者ですので、あくまで参考程度にしてくださって大丈夫です。
後、どうでもいいのですが、ブログを書き慣れていないせいでいわゆる『いかがでしたかブログ』みたいな文章になりました……今回の文章、いかがでしたか?
■
このブログの目的
プログラミングの勉強には実際に描くこと、技術系記事を書いて他人に残すことなどが良いと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タグについては全く知りませんでした。」はい、つまり有効です。実戦で証明していくソルジャーの鑑。