成長観察日記

競プロとかPythonとかに関しての成長記録

年内に緑になれなかった話

「色変記事」はたくさんある。
けれども「色変できなかった」というネガ記事はあんまりない。
それならば、能天気マンによるネガ記事を書くぞ〜!と、筆を取らせていただいた次第です。
※去年の競プロアドベントカレンダーで書いた 競プロ初心者がやらなくてもいいこと の冒頭よりオマージュ

この記事には対象者、というか、読んで欲しい人がいます。

  • 競プロやるのがつらくなってる
  • なんだかTLの雰囲気がいやだな〜と思うことがある
  • 競プロから離れるか悩んでいる

など。競プロや、界隈への想いが、下方に向かってる方。

選択を強要する内容ではないため、後押しとかはできないかもですが…
下方の気持ちを1年間抱えて考えたわたしの過程で、何かがあなたのためになれたら、とってもうれしいです!

では。
こっから先は算数から初学して、1年で茶色になった社会人競プロerの、2年目の記録です。
※1年目について詳しくは ABC283で入茶しました!〜成長日記〜

いつも通りエッセイです!技術的有益情報は、ないよー!

んじゃどうぞ、よろしくお願いします。

現状

レート:687

あと113…え、113?!旧実家の部屋番号だ。あらまあ!

problems

去年と今年で解いた問題数の差

2022年 月別AC数 (総AC数) 2023年 月別AC数 (総AC数)
1月 21 (23) 68 (868)
2月 7 (30) 58 (910)
3月 2 (32) 50 (960)
4月 1 (33) 19 (979)
5月 0 (33) 20 (999)
6月 0 (33) 48 (1047)
7月 36 (69) 82 (1129)
8月 26 (95) 100 (1229)
9月 121 (216) 60 (1289)
10月 310 (526) 23 (1312)
11月 121 (647) 50 (1362)
12月 153 (800) 11 (1373) ※12/18本日時点
年総計 800 573


灰を埋めてしまった関係で問題の難易度が上がったことを加味しても、やはり大幅に下がってますねえ。ぐぬぬぬ…
※時期別の下がり方(3〜7月 / 9〜11月)の言い訳については、最後に今年の振り返りと合わせて書いたぜ!

定量的に見える理由としては、ただ単に精進不足ですね!
問題は、定性的な理由。まあ、人にはそれぞれ人生があり、色変できない要因はそれぞれ。
わかっちゃあいて目も向けたくない!のところを、敢えて言語化してみました。

世界一えらい!

どうして緑になれなかったのか

 少し影響した
★★ 影響した
★★★ 大きく影響した



  • 転職活動をはじめた 

人生に趣味よりも優先するものが出るなど、予想だにしてなかった。
実際はじめてみたら、エディタ開くとWEB関連の勉強したくなるし、コンテスト以外の日にはPython書かない、ということが当たり前になっていった。
その代わり、WEBでできることは、めちゃ増えた!うれしい

そしてこの記事を公開するタイミングでなんと!競プロオタク語りしたおかげで(?)内定が出ました!
本当に嬉しい、ありがとうございます…!!
転職記事はまた別途書きます!



  • 問題を解く枷をつけた 

頭の中でずっと「精進しないとみんなに責められる」みたいな、謎の妄想があった。どうして…?
やりたくないのに無理矢理問題を開く、考える、嫌になる…みたいな期間があって、なかなか負のループから抜けられなかった…

そういうループから抜けるのはいつだって「休むこと」である。うむうむ!



  • 仕事が激務すぎた ★★

茶色になれたことで「がんばれば、できる」を過信してしまい、仕事で「NO」を言わなくなって爆死した。おばか…



  • 競プロ界隈での人間関係をがんばりすぎた ★★★

問題じゃなくて、人間関係について考える時間が、膨大に増えてしまった。
今年最大の反省は、今までの人生で出会ってきた人たちと、同じような頻度と距離感で、インターネット上のコミュニケーションをしてしまったこと。

仲良くするのが悪いのではなくて、相手によって距離感、頻度などは、しっかりと吟味しないと逆にトラブルになるということですね…!
複数の人間関係に対して、ここまで頭を抱えることが連発するのはじめてで、自分がいかに考えないで人と関わっていたかを痛感した。

1年を通して、たくさん失敗して、学ばせていただいた。
すっごく傷付いたこともあったし、とんでもなく大変だったけれど…周りの人たちのおかげで、なんとか乗り越えられた。
本当に、ありがとうございます。いつも。



ところで
わたしがAtCoderをはじめた当初の目標は「茶色」でした。
「まず茶色」ではなく、算数力底辺四則演算からスタート!の自分にとっては「目標が茶色」。

小さい頃から、家庭の金銭状況や親の思想の関係で「やりたいこと」を叶えられない経験を、たくさん積んでしまった。
チョコレートを食べたい、炭酸飲料を飲みたい、アニメを見たい、漫画を読みたい、ゲームをしたい…そして「勉強をしたい」

周りを見渡せば当たり前に許されている、なんなら推奨されていることは、我が家では「禁止」とか「嫌厭」されていた。

この歳になって自覚したのは、無意識にやりたいことを、親の代わりに自ら否定する癖があるということ。
そして、社会性が育ち「やりたいこと」を求められるようになると『叶わないやりたいこと』を作り、諦めるしかない環境に身を置いて、叶わないのを環境のせいにする癖がついてたということ。

叶えたら、続ける責任が起きる。だから、叶えることから逃げていた。

気づいた時、とっても、こわかった…あくまで癖だから、もちろん全てではないが。
勉強ができない環境下で、想像や安価なものだけで作り上げられる、かつ職業として叶える門が狭い「漫画家」や「音楽家」を将来の夢に置き、諦めていく過程は、両方の癖を体現していた。こわ!

なあんて、大袈裟に書いたけれども。
生きていれば、多かれ少なかれよくある、陳腐な話!
だから、これを読んでくれている記憶のどこかにも、きっと似たようなことはあるはず。

ごちゃごちゃ書いちゃったけれども

  • つまり、本心では年内に緑になりたいとは、思ってなかった ★★★

これが最大の理由!
だから、なれなかった、というより、ならなかった。が正しいな、と思います。

ちなみに、どうして2022年内に茶色になれたのか

実際、茶色は『目標』とか、そんなかっこいいもんじゃなかった。
「paizaSになって褒めてもらいたい、周りに喜んでもらいたい!AtCoderで茶色になれば、それが叶う!」という、ただの無謀な憧れ。
※詳しくは 2年前から夢だったpaizaランクSになった話

つまり、茶色は、高校3年生の夏に抱いた「普通になりたい」という、強烈な憧れとかなり近いものがあった。
※詳しくは 不登校児が願い続けた「普通になりたい」を忘れた話

緑という色に対して強い憧れがあるかと言ったら…ない!(どーん!!)
翠富士はだいすきだし愛してるし尊いが、わたしはどう頑張っても彼にはなれないし、なってしまったら推し活が捗らない!!

すみません話がずれましたね、まったくこれだからオタクは。

なので、わたしが茶色になれたことって、本当に素晴らしいことだったんだな〜、と。1年のラグを経て実感した。 嬉しいというより「よくやった、すごい」という気持ち。他者からの賞賛よりも、自分が自分に向ける賞賛、とても貴重で、満たされる。

だから、逆に考えてみると

強い憧れを叶える能力が、わたしにはある。 たとえ、どんなに無謀なことだとしても。

他者の評価が達成に介在しまくる「正社員になりたい」という想い(転職活動)は、ちゃんと叶った!やったー!
だから、今後また強烈に望むやりたいことは、どんどん叶えていってあげたい。
取り繕った『やりたいこと』とはさよならして、憧れに成るための努力。もっとしていきたい。
次の憧れに出会ったとき、それを追う時間を自分に作れるような状態にしておきたい。

それが、いまわたしがいちばん憧れを抱く『やりたいこと』だな!って、思います。

色々あったけど、競プロにはたくさん人生を変えてもらって、すっごく感謝しています。
だから、焦らずゆるく長〜く、続けていきたいな。

緑になるために必要だと考えていること

  • 「精進よりも優先してよい事柄があるのは当たり前」で、やりたいときにやる!

自分を追い込み成長できるのは、とてもすごいこと!
だけど、果たして今は、競プロのレートを育てるべき時期なのか、を見極められると、もっと賢くなれてハッピーだな!と思いました。
やはり、何事にも賢い人はかっこいい!かっこいい競プロerになりたーい!



  • 人間関係のがんばりすぎを減らす

ここ最近「X見たくないなあ」「スマホ見ないで友達と話している方が楽しいなあ」と、インターネットから逃げて現実を充実させている過程で気がついてしまったのは…がんばらないといけない関係って、長くは続かない、ということ。
本来友人関係って、仕事の人間関係と違って、頑張るものではなく楽しむためのもので。負荷を感じたら自分の世界へ逃げるとか、ちょっと距離を置くとか、そういうことしていいんだ。という、学生時代に学ぶことをやっと学べた。

そういう冷たくなっていく自分に自己嫌悪で忙しいときもあったけれど、相談に乗ったり乗られたりの過程で、だんだん納得していった。

非競プロerの友達からの言葉で、目が覚めたので置いておきます。

「わたしは、去年あなたが楽しそうに競プロの問題に取り組んでる姿が好きだったよ。今年、競プロの人間関係に取り組んでるあなたはとてもつらそうで、見ていて苦しい。」



  • 落ち着いて勉強できる環境を整える

これに関しては内定が決まったこともあり、だいぶ安心して勉強に専念できそう。安心安全が第一だ!



  • 健康と健全を取り戻す

しばらくレート爆上がりしていた期間は「運動して、お風呂入ってからABCに出場する」をルーティンにしていた。 ちなみに、運動しすぎた回は下がった!わーん

現実で動いて、汗流して、息をして。 自分の頭と体をしっかり整えてあげると、無駄な思考減って得意のはやときできるんだな!と思います



  • 数学の勉強を再開する

去年明らかにレートが上がった時期、中学数学を勉強した直後だったのよね。
いや〜〜黄チャートは難しすぎて放置しちゃった。
自分に合った学習本がちゃんと世の中にはあるので、そちらで高校数学!がんばります!

今年のまとめ

個人的に今年頑張ったので記念にコーナー!!
いやー、本当にがんばった1年だった!

1月

  • 仕事で新しい動きがあって、毎日深夜2時くらいまで作業してた
  • 調子乗ってRatedで出たARCで落灰!おおん

2月

3月

3月18日、あの日の「楽しい」は、わたしではなく、心がダメになったわたしを支えてくれた人たちのおかげなので!そこんとこよろしくです。 「やってよかった」と、今なら言える。そう思わせてくれるきっかけをたくさんくれたたくさんの人たちに、ひたすらありがとうである。

  • 沖縄と北海道を反復横跳びしてマイルを溜めまくった

4月

  • 傷を癒やしつつ、仕事をする機械になっていた。後で気づいたけどめっちゃ稼いでた!すごい!

  • ふ、と出たコンテストでちゃんと勝てた!

  • 好きな人とディズニー行くという青春をした。ありがてえありがてえ…

  • 荒吐ロックフェスに初参戦!5年ぶりにELLEGARDEN観て感動しすぎて、8年ぶりくらいに熱出す風邪をひいた。

5月

  • 北海道に渡り、風邪のあとぜんぜんご飯食べられなくなって、7kgくらい落ちた!ちなみに速攻戻った。もったいな!
  • 食べられないのに焼肉ご馳走してもらうとか、一緒にお寿司食べに行ってもらうとか、周りからの愛で食欲が回復

6月

  • ずっと達成したかったことが叶って、友達にお礼言いに回っていた1ヶ月だった。賞金渡したりした。
  • 精進復活し始めた!
  • 月末〜翌月初はまた青森〜旭川の旅をした!りんごジュース美味しかった!

7月

  • 人生初の川釣りに行って鮎を釣って食べたり、花火大会行ったり、買ってもらったFFXをやり込むなど…めっちゃ、夏した!
  • 京都の友達に焼肉ご馳走しに行ったり、おじいちゃんの最期(と言われていたが、ありがたいことに今も生きてる)に会いに行ったり
  • この月もどうかしているくらいに仕事していた。とっても稼いだ。えらい!

8月

  • 精進鯖に参加し、完走した!けむにくくんありがとう!
  • E8さんの高校数学本配信をした。微積分の概念がわかった時の感動、今も忘れない…
  • CodeQueenに出場した!
    ※詳しくは 女性オンリーオンサイトイベント【CodeQUEEN 2023】に参加した話
  • 未来館行って感動しまくった!
  • FFXを一日中やって酒を飲むという、大学生でやりたかったゲーム三昧の日を送れた!
  • 2年ぶりのSWEET LOVE SHOWERでたくさん夏フェスを楽しんだ!
  • 月末〜翌月頭は友達と札幌〜新潟へ

9月

  • 小樽〜新潟のフェリー移動中に船上競プロをして爆死した…
    ※詳しくは 船上競プロのしおり

  • 船上で大暴れレベルに歯が痛くなって、帰ってからすぐ人生初の歯医者に行ったら、そのまま親知らずを抜かれてびっくりした!お医者さんは「いきなりラスボスだね〜」と笑っていたので、泣きながらメリーさんの羊を歌った…(カオス)

  • びっくりしてたら初のコロナになった!後遺症がつらすぎて、精進ぜんぜんできなくなった…

  • FFXクリアした!!人生でクリアしたゲーム3作目。どえらい感動

  • 父の家に友達と遊びに行った時、仕事の話をしていて、父に言われた「お前、そのままでいいのか?」が深く刺さった。
    全然よくない!になったので、12月で今の仕事からは離れよう、と決めた。

10月

  • 決めると早かった。ほぼ向こう都合で、委託仕事の1つから急に離れることになった…!

  • そのあとすぐチャリ盗まれたけど、友達がチャリくれた!やさしすぎる!

  • 転職活動、というか、就職活動したことなかったので「転職(就活)」を開始!

  • ちょくだいさんれもんさんの結婚式で、有志を募ってお花を贈った!AC!

  • 好きな人と旅行行って人生初の対面告白をしたうおおおおおお

  • 体力を使い果たしたので、その翌週友達と長野旅行してのほほんした

11月

  • 警察で競プロerとの対人トラブルを相談しながら精進したらREが出た!警察署で競プロの実績解除

  • 対処をしてもらえることになった代わりに、トラブル相手と対面する場になるオンサイト・懇親会などには参加しない、という約束をすることになった。少し悩んで、反省と責任を果たすために了承した。ということで行けなくなっちゃった会がたくさんありました。この場を借りて謝罪です。ごめんなさい…

  • 心がしゅん、となりかけたので、友達のツテでまた北海道へ。すすきのでたまたま出会った人々と音楽とお酒を楽しみ、回復どころかとんでもパワーチャージして東京へ戻った!

  • そして、転職活動をがんばりまくりながら、新しい制作の仕事もばりばりのばりに頑張った!

12月

  • D論コンにチーム参加した。茶色のわたしにとってはとんでもなく難しい問題に、爆笑しながら挑めて、とっても楽しかった!

  • ファミレスでロリハとセグ木を教えてもらって、理解が遅く脳が壊れそうになって、本当に楽しかった!

  • 全力で生きる疲労は脳を蝕んで、調子良かったレートも、下がり続けた…が、ちゃんと回復傾向を見せはじめたよ!

そんなで、転職活動に奮闘していたら、もう12月は半分が過ぎたのね。
今年は、かなり駆け足で『20代までにやるべきだったこと』を経験したな〜。

競プロをはじめるきっかけになった神に「もう競プロやめたいです」と弱音をもらしたとき

「競プロは、ひとりでもできるので」

と言われたことが、いま、すごく力になっている。 やるもやらぬも、休むもがんばるも、他人には関係ない。つまり、誰かにされる強制は、何も気にしないでいい。

わたしたちは、毎週コンテストで、ひとりで戦っている。 知識や知見の共有も確かに有用だけれども、レートのために戦う時は、絶対にひとり。

そういうところが、競プロの好きなところのひとつです!
だから、来年も競プロとは「嫌いにならない程度の距離で、関わり続ける」が目標です。

好きなものや人を嫌いになるのは、かなしいからなあ。

ゆっくりと、競プロの好きなところを思い出せて、そして、やっぱり続けようって思えた!
それに、人間関係もトラブルばかりじゃなかった。むしろそれ以上に、頼れる友達や、同志や仲間ができて、とっても充実した1年だった。
この記事書けて、それを思い出せたよ!とってもよかったー!

さいごに

今年もアドベントカレンダー立ててくれたりゅーすけさんに、最大の感謝を送って締めます。きっかけくれてありがとう!

ではではみなさま、良いお年を!

2年前から夢だったpaizaランクSになった話

うれしい

うれしすぎる

2年間、ずっと夢だった。本当にうれしい

どうしてこんなにうれしいのかを伝えたいので書きました! 相変わらず小説です。有益な情報はないです…ということで、よろしくおねがいします!

大学卒業〜

2014年4月に大学を卒業。 音楽の情熱と一緒に夢を追いかけつつ、アルバイトやフリーランスで制作業務をする日々。

しかしまあ 夢は夢で終わらせたほうがよい ってことも、あったんですよね。
そんな素敵なことに気付けて、2019年2月、満員御礼のライブハウスにて、表舞台での音楽活動を終えた。

それから2年後、とある派遣に登録したところ「弊社の社員になりませんか?」とスカウトを受ける。
タウン●ークでアルバイト応募したら、タウン●ークから「うちの社員にならん?」って言われた感じですね。最初、何が起こったかわからなくなるやつ。

なんと、書類選考もすっ飛ばし、いきなり社長面接。
そのあと会議室で10分くらいぼーっとしてたら「おめでとうございます、内定です!」と、内定通知書をいきなり渡され、口をぱくぱくするしかできなかった。

机の下でこっそりiPhoneをいじり、母に連絡。「まさかのいま内定でた!就職だ〜!」と送り、連絡したい人々の顔が次々に浮かんできて、とてもぽかぽかした気持ちに。

そんな感じで、2021年4月、はじめて†しゅうしょく†を、しちゃいました!

就職

配属されたのは、就活事業部。

週3日の在宅勤務(当時は、フリーランスの仕事を並行したかった)で、出社は2週間に1回。

文書の校正をしつつ、WordpressやHubspot CMS機能をいじいじする人だった。
コードを書くのは楽しいけれど、部内には他にコーダーさんがいなくて。コーディングでわからん…なところを聞ける人は特にいなく。それがちょっとさみしかったな(持ち前の馬力で全て解決していた。えらい)

競プロとpaizaを知る

夏頃に神(わたしに競プロを伝来した人)と、フリーランスの仕事で出会い、競プロの存在を知る。

フューチャー社さんの文章校正をしていた時に、直属の上司の方が【競プロ】を【競技プロ】と校正していたのを見て、すかさず「あ、これはそのままでよいです。競技プログラミングの略称は、競プロです。」と訂正できたの、とてもよい思い出。
(当時は競プロといったらフューチャー社さん!というイメージが強かったし、校正してて競プロという単語に出会ったのは、パナソニックさんくらいだったかな)

ちょうどその頃、部内でpaizaのスキルチェックがテスト導入される。
出社時に、B以上がボーダーラインだけど、高すぎるかなあ?という話を小耳に挟んで「すごいなあ、プログラミングできる人々…結局、やりたいと思っているだけで、ちゃんと勉強できてないや。」と、ほんのり切なくなりながら、営業さんにいただいたヤクルトをごくごくしていた。
※個人的に、CMS構築は組み合わせ要素が強いから、PHP / JavaScript / HubLが書けても「プログラミング」ではなく「コーディング」してる、という気分。ちなみにCSSは大好きよ!オタク喋りになってしまうわ!

paizaSランクのすごさを知る

秋頃のとある出社日、昼ごはんにマック頬張って帰ってくると、部内が湧き上がっていた。
なんやなんや?と聞きに入ると、paizaのコーディングテストでSランクの人がいた、とのこと。

「Sとか超優秀じゃん!どこの企業さんにも紹介できるよ〜」

すごいすごい、とみんな言うので、相当すごいんだろうな、と思ったと同時に「自分もランクS取れたら、こうやって喜んでもらえるのかな」とも、思った。
でも、まだ競プロをはじめる気には、なれなかった。数学もプログラミングもばっちばちにつよい神だからこそ楽しそうにできるのであって。両方すっからかんの自分なんかにはできっこない、と思っていた。

AtCoder茶≒paizaSを知り、AtCoderに登録する

冬頃のとあるオンライン飲み会中、神に「そういえば、paizaSってAtCoderだとどんくらいすごいんですか」と聞くと「レートでいうと下から2番目、茶色です。さらにその上が7段階あります」と答えてくれた。

チューハイをこぼした。めっちゃびっくりした。

あんなに希少扱いされているSランクよりもすごい人々が、ごっそり、いる…??ええ……???
と、一般人からしたら、意味わからん世界だった。なんでいまこんなにどっぷりなんだ?慣れってすごいねえ

「じゃあ、AtCoderで茶色になったら、paizaSになれますか」
「ですねえ」
「こんなわたしでも、茶色になれるんでしょうか」
「もちろんです!」

おめめがたいへんにキラキラしてたとおもう。
当時青コーダーのすごさの感触すら「すごすぎてすごいということしかわからん」のレベルだった。語彙がなくなるやつね。
そんな人に できる と言われたら、できる気がした。

そんな経緯で、いつもの酔っ払いの勢いでAtCoderに登録し「burioden」が生まれました。

ID名の由来、語ってなかったのでついでに。
登録するときに咄嗟に、会社でのあだ名「ぶり」+当時のアーティストネーム「おでん」を、くっつけた。
会社でのあだ名は本名由来で、営業さんがつけてくれた。橋xxの橋→bridge→ぶり。個人的にぶりはいっちゃん好きな魚なので、すごくうれしかった。
アーティストネームも、友達がつけてくれた。最初の案が「ガパオ」だったけれど、ちょっと匂いそうなので他の…とわがままを言ったら「えー、じゃあおでん」とぶっきらぼうにつけてくれた。
おでんはいろんな具が入ってて自分みたいだな、と思ったので、とても嬉しかった。

ところが、その直後、もろもろあり…悔しながらも休職期間に入ってしまった。
休職期間に入った直後、はじめてABCに出て、0完した。Weird Functionめ…

休職〜退職

フリーランスの仕事はぼちぼちやりつつ、頑張って生きていた。
が、なかなか復職許可が降りず、3月に休職期間満了で自然退職。

かなり悔しかった。もう二度と就職できないんじゃないか…?って不安も、あった。

それでも「茶色になれる」を信じて、ぼちぼち競プロを続けた。
一度は諦めたものの、神と深酒して再び決意したりなど。根底にある「paiza Sになりたい」が、ゆらゆらしながらも競プロのモチベを支えていた。

※この辺詳しくは入茶記事で語っています

はじめてのスキルチェック D→Cランク

競プロに戻ったあと、すぐに初のスキルチェック。
初めての提出は2022/07/12 00:19「D189:何周年の確認
無事正解して、Dランクになった!わーい!

さすがに簡単だったので、5分後に「C084:【キャンペーン問題】枠で囲む 」を正解して、Cランクに。

このままB行くか?と思いきや、当時のAtCoderレーティングが54という、とんでもなくよわよわ灰コーダーだったわたくしは「ボーダーと呼ばれていたBランクに、そんな簡単になれるわけないだろ」と、弱気にいったん離脱。

paizaの問題はご存知の通り、ランクアップのチャレンジは1度だけ。わからなくても他人には聞けず、間違っていてもどこが間違っているかわからない。
たいへんもやもやする孤独な戦いのため、正直避けていた…という節も、なくはない。

C→Bランク

9月24日、忘れもしないABC270。はじめて神と一緒に出たトヨタのコンテストで、ひさしぶりの0完をした。1-2-4 Testめ…
すっごく悔しくて、その後精進の塊になったのを機に、4日後の28日にBランクを受験。ちなみに、当時のAtCoderレートは96。
たしかタイトルだけで選んだ「B095:カラオケ大会」は1ケース落としてしまい、無念の89点。

「やっぱBランクは、むずいよなあ…」と思いながらも、後少しで行けた感覚はあったため、続けて「B117:回る教習車」を受験。こちらはしっかり100点が取れて、めでたくBランクに!

Aランクに、なれない…

11月14日、はじめてAランク問題に挑戦。
A066:連勤記録」で全問題TLEし、0点(どうして…?)
ちなみに、当時のAtCoderレートは198で、右肩上がりをし始めて調子に乗っていたのだろう。その後すぐに解いた「A052:階段登り」も惨敗。

やっぱり、Bランクのようにはいかない。Aが壁すぎる。と、一旦諦め、AtCoderに戻る。

入茶した!が、Aランクになれない

12月24日クリスマスイブ、ABC283で大勝利をし、クリスマスプレゼントとしてAtCoder茶色をいただいた!やったー!
そのうれしさのまま記事を書き(今と同じことしてるなあ)投稿した後に寝て昼夜が逆転。落ち着いた26日早朝、再びAランクの「A057:最長スワイプ」に挑戦するも惨敗。

「やっぱり茶色になっただけでは、Sは程遠いのか…そりゃそうだ、わたしの武器って、はやときだもんなあ…(頬濡らす涙)」

年が明けた2023年1月7日に挑戦した「A023:週休2日制」もクリアできず、しばらく期間を空け、7月20日に挑戦した「A053:RGBの個数」もかなしい結果に。ちなみに当時のAtCoderレートは568。

半ば諦め気味に、キャンペーン問題をチラリと解いたりなどしていた。

もうAがダメならSだ!もちろんなれない…

7月22日、またトヨタ主催のABC311で負ける。レートは548に落ち、それまでの連勝記録がストップ。2ヶ月間の停滞期に入る。
悔しくてはじめてのSランク問題に挑戦してみる。AがダメならSランクだろ!!(????)という思想、嫌いじゃない。

S039:ボスの部屋」を受験し、もちろん惨敗。レートは横ばい。ぬーん

転職活動をはじめる。でもまだAになれない…

10月に転機が訪れ、転職活動を開始。
つまり、また†しゅうしょく†をするために動き始めたのだが、いかんせん就活もしたことがなく、体当たりでたくさんを学ぶ。

そんな中、11月4日、HHKB主催のABC327で勝ち、AtCoderレートが643に!やったーー!!
ということで、その3日後の7日にまーた挑戦したSランク問題は「S049:開発の見積もり」 なんというか、例に漏れず負けた。99分の思考中、諦めが出てしまった部分が災いしていた…

やったー! Sラ…じゃない、Aランクだ!

翌週の11月11日、あれだけ負け続けたトヨタ主催のABC328で大勝利し、AtCoderレートが694に!すごい!!
2日後の13日、トルコアイスか?ってくらい粘度の強い諦めの悪さを発火させ、Sランクの「S007:データヒストグラム」に挑戦。

なんと。はじめて!全テストケースに正答し!見事Sラン…ク、には、なれなかった。

かけた時間が 144分49秒 だったから(やばい)

しかしレーティングは上がり、無事にAランクへ!やったー!!あとちょっと!!

やったーやったー!最終面接に残れたし、Sランクになったー!!

そして、本日11月29日。
paizaを利用した転職活動で、はじめて最終面接に残ることができた。
友達と焼肉を食べた。厳密に言えば、いい肉の日だったから焼肉に誘い、エレベーターホールで待っている間に結果が届いた。

帰宅後、ナップザックDPを履修。成長!その後、最終面接の内容確認で開いたpaizaのページ上部に「S002:最短距離を測る 」がちらりと見える。

「なんか、いける気がする」という軽やかな類の勘は、当たることが多く

20分4秒で正解!
ついに!Sランクを達成しました!!!やったあああああああ

直前11月25日のABC330では惨敗し、AtCoderレートは698(-23)してしまっていたが、paizaでは勝てた!
選考通過のうれしさが原動力だったことと、勘を信じてよかった。とてもうれしい。

これから

あした、というか、今日か。
ダメもとでというか、ただ自分のエゴだけれども、直属の元上司の方に、連絡したいと思っている。

休職に入る時、勢いで約束してしまっていた。
「休職期間の3ヶ月以内にpaizaSになって、戻ってきた時にもっと貢献できるように。頑張って勉強します」と。

やり始めたら3ヶ月は無理オブ無理だったのだが…(愚か)

結果的には苦い状態になってしまったけれども、paizaSになるという約束を果たせたこと、元気でやっているということは、やさしく軽やかに伝えたいな、と思う。

これが最後のわがままなので。きっと。人生初の上司なら、聞いてくれるだろう。なんて甘えてみるよ。

よーし!転職、がんばるぞー!!

女性オンリーオンサイトイベント【CodeQUEEN 2023】に参加した話

はじめに

kenkooooさん、並びに運営に関わってくださった方々、本当にありがとうございました!!
自分のレートでは絶対にできない、貴重な体験をさせていただきました…!わーい!

同時公開のAyunaさんの記事も読んでね!!!

ayuna-stpyko.github.io

まず…参加記が爆裂に遅れて申し訳ございません(2ヶ月と17日分の土下座)

遅れた理由のひとつでもある注意事項を、最初に記載させてください。

この記事には、心がちくりする話が、いくつか含まれます。
そのため「参加記」ではなく、わたしを含めた女性競プロer達の「物語」、つまりいつも通り、小説としてお楽しみいただければ幸いです。

つまり、いつも通り1万4000字の長編なので、あったかいお茶🍵などお供に、ごゆるりとどうぞ!

CodeQUEENとは

kenkooooさんが代表を務める合同会社 AlgoParade 主催の予選・本選の二本立てコンテストです!

予選はいつも通りオンライン。 本選は、AtCoder史上初の試み、女性(非男性)を対象としたオンサイト(オフライン会場開催)。

概要はこんな感じ

  • 7/1(土)の予選を勝ち抜いた上位50名(高校生15名、大学・大学院生20名、その他社会人15名)が、8/6(日)のオンサイトで戦うよ!
  • 本選オンサイトの参加資格は「高校生以上」の「非男性」であることだよ!(詳細は下部リンク先)
  • 女性のプログラミング関連人口って少ないよね…機会を増やしたいぜ!(下部リンク先にある、青木さんの文書が素敵なので転載)

日本国内の男女比がほぼ1:1であることを考慮すると、STEM分野において男女比が偏っていることは明らかです。性別によって能力に差が出ることはなく、プログラミングに性別は関係ありません。

このような偏りが発生する原因の一つとして、歴史的、社会的な風習(無意識の偏見)が挙げられます。特定の属性を持つ方々に機会が提供されなかったと考え、今回開催の運びとなりました。このような取り組みによって、今までプログラミングやSTEM分野に興味がなかった方、注目されてこなかった方々の参加を促すとともに、性別に関係なく、誰もがプログラミングに熱中することが当たり前だという社会的な合意を目指しています。

atcoder.jp

予選に向けて

コンテストがオープンになった時、競プロの歴史の1ページがめくられた音が聞こえました。期待もあり、不安もあり。
とんでもなく勇気と度胸と想いがある試みだな、と、同い年である主催者kenkooooさんに、足を向けて眠れない日々が始まったのであった…(たぶん真東にはいないはず、と信じながら毎日ぐっすり寝てます)。

さて。なぜ不安なのか。
2022年9月ごろに時を戻します。

わたしが競プロ界隈に馴染んできた、秋ごろのこと。
その頃は、TLを眺めながら「性別、わかんないな。いや、全競プロerは、アイコン通りの美少女やもふもふ(動物)なのだ!」という、性別について考えることは、脳の無駄遣いである〜な状況でした。

年末ごろ、Xにスペース機能が搭載され、競プロerの声を聞く機会が増えました。そこではじめて「あれ?男性比率めちゃくちゃ高いのでは…?」と気付いた賢いぶりちゃん。やー賢いねえ。深夜テンションが始まってまいりました(現在午前1:41)。
自分が男性恐怖症持ちであることと、女性は女性であることを秘匿しがちな界隈の雰囲気から「半クローズの女性専用discordサーバーがあると、安心できるかもしれん」という、エゴと人のための半々な想いで「競プロ女子部」を設立しました。

2023年3月、ちょっとした荒れごとに巻き込まれました。
その際に燃え上がった理由のひとつに「女性だから」という性差問題があったため、CodeQUEENが生えた際、荒れごとを思い出さずにはいられませんでしたね。ぐへへ

コンテストが生えた直後のTLでは、CodeQUEENについて、どちらかというと否定的な議論が勃発しました。

時が経ってしまったので、内容はうろ覚えですが

  • 性差で賞金獲得チャンスに差が出るのはいかがなものか
  • 非男性の定義が曖昧
  • オンサイトに行けるレート条件が低くなりすぎる
  • 本戦順位表や、本戦に行く人の情報が非公開ってどういうこと?

などなどが議論されていたイメージです。

わたしはめんどくさがりやの平和主義で、議論には基本的に参加せず、するにしても道化をするタイプ。 が、たま〜に出るブラックぶりがつい顔を出してしまい

「そんなこと言う人がいるから、オンサイト順位表が非公開という配慮になったり、CodeQUEENが開催される意図にもある『女性エンジニアを増やしたい』が妨げられ続けているんじゃないかなあ(を、社会性オブラートに包んだもの)」

を投稿するだけして逃げるという、せこいやつをしたり、らじばんだりをしました。らじらじ!

そんなちょっと不穏な雰囲気のまま、予選が開催される7月になりました。

予選

社会人であるわたしは、上位15名に入れば、本選オンサイトに行けます。
茶の自分にとっては、夢の夢のまた夢…いつも通りを執り行うぞい!と思いながら挑んだ予選の結果は

atcoder.jp

全体4004位!
Highestを更新!!
予選通らんくてもうれしい結果!!!
まあでも予選通過メールは来ない!それはそう!!

と、わっきわっきしていたら、翌日、また曇り気味のTLを観測。

どうやら、参加登録時に文章をあんまり読まず、参加意思の有無等の選択肢を『はい』にした勢(つまり、本来は本戦に出場できない勢)が、次々と発覚しているようでした。

そのようなことが起こると、併せて起こるのが「繰り上がり本戦出場」です。
TLや女子部では、定期的に繰り上がり本戦出場の知らせが舞い込んできました。おめでとうはっぴーであります!

実はかなり抜けていることで有名なわたしは、メールのチェックよりも先に、友達からの「本戦行けることになりました!自分よりも順位が上であるぶりさんも行けるはずです!!」というお知らせの後、kenkooooさんからのメールを見て、叫びました。あれはいいシャウトだった…

そんなこんなで、女性競プロer社会人上位部門!として、本戦に参加することになったのです!

本戦に向けて

初の試みにおいては、参加側にも、ドラマがありました。

個人的な悩みと、ターゲット的な悩みの解消

本戦出場の喜びも束の間、わたしは不安に押し潰されました。

冒頭で触れた『3月の痛い経験』の原因となったお相手と、オンサイト会場で鉢合わせするのでは…?という疑念が湧いたからです。

その時、わたしは近所のモスバーガーでサラダをもしゃもしゃしておりました。
店内BGMで愉快なラテン風音楽が流れる中、こわくてぼろぼろに泣くというコントラストが大変滑稽。わたしの人生、だいたいそんな感じ。

「またあの悪夢が帰ってくるのか…?」
「いや、まずはとにかく…人に相談せねば!」

びちゃびちゃの脳味噌で泣き言を書き綴り、信頼する数名に送りました。

「かもしれない」で参加を辞退するのだけは嫌だった。 もし相手が来るとしても、わざわざ自分側が辞退するということは、絶対に避けたかった。逃げるためにチャンスを殺すことは、ほんっとーに嫌だった。

そして、それと同じくらいに、こわかった。

同時に、競プロ女子部内でも
「自分みたいな非IT人材が、本戦に行っていいのか」
「主婦は、本選出場のターゲットではないのでは」
など、非難や不安に影響を受けてしまわれた、心優しい方々の声が上がり始めました。ニ"ャ"ア"ア"ア"ン

以下は、相談してくださった方へ、わたしから送ったメッセージの一部です。

「誰を大切にしたいか」だと、わたしは思います。
わたしは、自分を愛してくれている人、応援してくれている人、よい影響を与えてくれる人を大切にしたいです。
もちろん自分も大切にしたい。行きたいという気持ちを叶えてあげたいです!
◯◯さんは、どんな人を大切にされたいですか。

AtCoder社員であるかえでさんも「次が開催されるためにも、来てくれることが大事ですよ」と、女子部の雑談チャンネルにて、力強いお言葉をくださって。圧倒的ラブじゃ…

神(わたしに競プロを伝承した人)にも、わたしの泣き言を聞いてもらったところ
「無理して行かなくていいけど、自分にとって大事ではない人で消耗するのは勿体無いですよね」
という、さっきそれわたしが他の人に伝えたやつだ…な言葉をいただけて、心がぽかぽかになりました。

その夜は、言語化が難しい、プラスでもマイナスでもない不思議な気持ちで、チャリを引いて帰ったことを覚えています。道中でタクシー運転手と乗客が殴り合いの喧嘩しててすごかったが。あれ、かなりすごかったな…

その後、かえでさんにDMで相談させていただき、kenkooooさんにメールでお伺いしたところ、わたし個人の恐怖は、杞憂であったことがわかりました。
かえでさんもkenkooooさんも、丁寧にすぐにお返事をくださって、悩んでいた時間が吹っ飛びました。

ユーザーが運営に直接相談できるという文化は、AtCoderのかなりよいところだなーと、この経験をもって実感できました。

わあい!これで、安心してオンサイトに行けるどん!感謝感謝の感謝丸!!

色んな方に助けられたし、こうやって参加者同士で励まし合いながら本戦に挑む個人戦オンサイトって、かなり特殊だな、と、今になって改めて思います。

その後も、質問や疑問のシェアや、回答メールのシェアなど、女子部の雑談チャンネルはいつになく活発的に動いていきました。がんばえたてたひと…

そんな折タイミング良く、自分の性自認が「ない」ことを友達に気付かされ、わたくしぶり、24時間ほど精神と時の部屋に篭りました。
それは、ずっと気付かないように、見ないように誤魔化してきた、生きにくさの根幹みたいな部分で。
たくさん悩んで、たくさん泣いて、昔の自分が作った歌を聴いたり、同じ想いをしているであろう方の発信を受け取ったり。

1日散々考え「いや、そんなことどうでもいい」というところに落ち着きました。
わたしの身体は女性だし、その事実に対して違和感もない。何より競プロが好きで、その気持ちに性自認は関係ない。
だから堂々と「非男性」として、コンテストに挑んでもいいんだ、と。

この経験で、やっとわたしは「競プロer」になれました。
へなへなだった自分をやっと「戦う人」である、と自認できた。

なので、心が痛い話はこれにておしまい!

競プロ女子部バーチャルコンテスト

本選開催1週間前である7/30(土)に、勉強会や交流も兼ねてチーム戦バチャを行いました。 実は、これが初の女子部イベント…(ばっちゃーん)

時間設定は、本戦と同じく3時間。
1チーム3人構成、3チームの灰〜黄が参加。 というゲキムズな問題選定をしてくださったのは、seekworser(ぷせうど)さん。

大好評だったラインナップはこちら

終了後に突然の解説会を行い、参加と解説してくださった方々、本当にありがとうございます…!!
我がチームの大将は、記事を同時公開しているAyunaさん。もちろん頼りきりでした(だいちゅき)
が、自分の勘もかなり効きがいいんだな。と思える問題に2問も出会えたりなどして、とてもうれしい経験でした。ぷせうどさん、本当にありがとうです!

本戦

様々を乗り越え、ついにやってきた8/6(日)
当日は大変な猛暑日で、太陽からの応援がちょっとうっとおしかったです。ツンデレなので。

持って行ったもの

  • ぬいぐるみ(どんちゃん❤️)
  • MacBook
  • iPad
  • 携帯
  • 上記3点の充電器
  • 財布
  • チョコ
  • 「浜辺力士」という名を持つステキな折り畳み傘

会場にはペットボトルの飲み物が用意されていましたが、飲食禁止。水分補給はこっそりならOK、チョコなどちょいとした糖分補給は、会場外のロビーで行いました。

コンテスト前にやったこと

わたしは遅刻癖がひどすぎるため、コンテスト前にごはんエンカを生やし、コンテスト自体への遅刻を回避するクズプレイをかますぜ!

ちょうど前日夜に届いたHighestを更新Tシャツを着用、うきうきで会場・東京大学へ向かいます。

しっかし、くっそ暑かった。暑さに対する愚痴で全人類と仲良くなれるレベルの暑さ。

到着するやいなや現れたオシャレローソンに驚き「さすが東大は違うぜ!」とはしゃぐ。

遅刻防止お腹満たしエンカにご協力いただいたrinrionさんtomoeさんと、東大構内カッフェでオッシャなご飯をしました。

やばい おなかすいてきた(現在午前3:25)

そしていざ!会場である山上会館へ。

これはですね、東京大学構内の写真です。本当です。
かなり迷子になりました。思っていたより森だった。トトロ出てくるかと思った。

結果的に、実はGoogle mapに嘘つかれていて、会館の裏口に連れて行かれていただけという…
こういう「やばい!気をつけて!」を手軽に共有できるので、女子部という存在がありがたかったです。

無事、正面入り口からCodeQUEEN会場へ。

プログラミングコンテストだあ!

受付を済ませると、座席表を渡されました。すごい。試験みたい!
しかし、席が一番前と知って、若干テンション凹みに。問題解いている時のわたくし、たいへん、動きたい…後ろに迷惑かけちゃう

という凹みも、席についた瞬間凸みに!
見てこれ!大変感動!!やべーーーー!!オタク歓喜!!

事前エンカのおかげでちょっと早めにつき、他の席にお邪魔しまくりました。
競プロねこTのおかげか、向こうから声をかけていただけることが多くてねこありがとう…

Ayunaさ〜ん!と声をかけに行った時、前の軍団が異様な「強者」オーラを出していて、蛇に睨まれたカエル状態に…座席表をよく見ると、どうやら予選の順位順になっていたようで、まじでやばかったです。やばかったっす。かっこよすぎる。あの場に美輪明宏さんがいたら、オーラの色がレート色であることを教えてくれたかもしれない。

会場のことで印象に残っていたのは、お手洗いの配慮です。
男子トイレをぶっつぶして、山上会館内のほぼ全てのお手洗いは女性用に塗り替えられていました。中には女性特有の配慮などもしっかりされており、こう、なんだ…はわわわわ…となり続けるだけの魚になっていた。

オープニングセッションは「大変に就活だあ!!!」と感激しまくり。
ユニークビジョンの競プロLT会時も思いましたが、kenkooooさんは喋りが本当にお上手で、終始笑いが絶えない開会式でした。あれでかなりリラックスできたなあ。

「1位の賞金額!投稿と拡散しまくって!!」というkenkooooさんのお話にけらけら笑っていたら、撮り逃してしまった。すみません…わたしはそういう人間

せっかくなのでこちらのTシャツに着替えましたが、ロンTの上に着たのは暑くて後悔をした。

会場のWi-Fiがかなり遅めだったため、接続落ち着くまでデザリングでやるか、と。すぐに切り替えられるからMacBook & iPhoneのコンビはやめられねえぜ! (が、切り替えなどさっぱり忘れて、最後までデザリング参加でした。れれ)

ということで、さあいざ!本戦コンテスト!!

コンテスト中

途中ゲリラ豪雨が起こり、雷が苦手なわたしはそわそわしっぱなし。鳴るたびに揺れる心と体。そうビビり。

結果は無念の2完。しかも大量のペナを出し続けた。continueとbreakを間違えてな…(初心者)
個人的に「勝ちたい」と思っていた人には全員勝てた。それが何よりの誇り。

A問題

atcoder.jp

問題概要

文字列Sと、1文字Cを与えるよ。
Sの中のC→CCって感じで、Cを2つにしたバージョンのSを出力してね。
たとえば、S = abc, T = aなら「aabc」を出力してほしいよ〜

考察

Ohh...Thank you Python....

コード

# 入力
s = input()
t = input()

# 出力
for i in s:
    if i == t:
        print(i * 2, end="") # Thank you Pythonポイント
    else:
        print(i, end="")

感想

ありがとうPython。A問題提出時点では4位だった(えらい)



B問題

atcoder.jp

問題概要

N x Nの盤面の上に、N - 1個のクイーンがあるよ。
もう1こクイーン置けるか判定してね。置ける場合は、場所を知りたいよ!
置ける条件は、タテヨコナナメぜーんぶに、他のクイーンがいない、たったそれだけよ(たったそれだけなんだけどむずい)

考察

N <= 5000。全探索、枝刈りをすればたぶん間に合う。やろう

  • 最初に、何もないグリッド盤(何もない場所 = .)を作る
  • 入力を受け取りつつ、クイーンの場所を#に変える。そして、入力されたx座標とy座標を、それぞれ候補の行列から消すことで、置ける場所の候補を作る
  • 候補地すべてを、順番に「右下」「左下」「左上」「右上」全探索して、ひとつでも「#」にぶつかったらダメ候補とする。なにもなかったらOKで、出力して終わり

コード

#入力
n = int(input())
g = [["." for _ in range(n)] for _ in range(n)]

r_c = set(i for i in range(n))
c_c = set(i for i in range(n))

# クイーンの位置を受け取りつつ、タテヨコにクイーンがいない候補地を絞り込む
for i in range(n - 1):
    rr, cc = map(int, input().split())
    rr -= 1
    cc -= 1
    g[rr][cc] = "#"
    r_c.discard(rr)
    c_c.discard(cc)

# 候補地のナナメを全探索
for r in r_c:
    for c in c_c:
        # ナナメ4方向を調べる OKなら減らす
        cnt = 4

        # 右下
        flg = True
        for k in range(n):
            if r + k >= n or c + k >= n:
                break
            elif g[r + k][c + k] == "#":
                flg = False
                break
        if flg:
            cnt -= 1
            
        # 左下
        flg = True
        for k in range(n):
            if r + k >= n or c - k < 0:
                break
            elif g[r + k][c - k] == "#":
                flg = False
                break
        if flg:
            cnt -= 1
        
        # 右上
        flg = True
        for k in range(n):
            if r - k < 0 or c + k >= n:
                break
            elif g[r - k][c + k] == "#":
                flg = False
                break
        if flg:
            cnt -= 1
            
        # 左上
        flg = True
        for k in range(n):
            if r - k < 0 or c - k < 0:
                break
            elif g[r - k][c - k] == "#":
                flg = False
                break
        if flg:
            cnt -= 1
            
    # ナナメ4方向全てなにもなかったらOK
    if cnt == 0:
        exit(print(r + 1, c + 1))

print(-1)

感想

本番、2ペナ出してもうた理由が、breakをcontinueって書いててTLEしていたからでした。
次の週のABCでは逆をやって(continueにしたいところをbreakと書いていた)見事に爆死したのでおぼえた。
3つの変数をこちゃこちゃするの苦手なので、ちゃんとタテヨコナナメ判定の関数を作りたい。作る。絶対に作る!!



C問題

atcoder.jp

問題概要

N個の頂点グラフがあるよ。SとTという整数があるよ。 頂点Sと、頂点Tから、2人が同時に「よーいスタート!」ってして、まあまずは頂点1へ行ってみよう。 最短経路で向かった時、2人の道のりが被ったところがあると思うんだよね。その被ったところの数を、頂点1〜Nまで、全て調べて出力してね。

考察

DFSかBFSだな(ということはわかって、本番が終わった)

かなり心に残ってて、その後知能が下がり続けた2ヶ月もずっと考えていた。
にょぐたさんの解説が、単純明快なのにどうしてそうなるかわからなくて、とある日は四六時中考えていた…

で、やっとわかった。

BFSで、Sから各頂点(j)、Tから各頂点(同じくj)への最短距離を求める。

Sからjまでの距離と、Tからjまでの距離を足したら「被るところ」と「だぶるところ」が出てくる。
被るところは、SからTまでの距離。なので、引く。
その引いた数はそもそも2重にだぶっているので、2で割る。
最後に「距離」と「個数」を合わせるため(閉区間を半開区間にするため)に+1しておわり。

区間の重複を消す技、めっちゃ感動した…!!

コード

#入力
from collections import deque

n, s, t = map(int, input().split())
g = [[] for _ in range(n)]
for _ in range(n - 1):
    a, b = map(int, input().split())
    g[a - 1].append(b - 1)
    g[b - 1].append(a - 1)

# 0-indexedに直す
s -= 1
t -= 1

dist_s = [-1] * n
dist_s[s] = 0
q = deque()
q.append(s)

# Sから各頂点jまでの最短距離
while q:
    v = q.popleft()
    for x in g[v]:
        if dist_s[x] == -1:
            q.append(x)
            dist_s[x] = dist_s[v] + 1

dist_t = [-1] * n
dist_t[t] = 0
q = deque()
q.append(t)

# Tから各頂点jまでの最短距離
while q:
    v = q.popleft()
    for x in g[v]:
        if dist_t[x] == -1:
            q.append(x)
            dist_t[x] = dist_t[v] + 1

for j in range(n):
    ans = (abs(dist_s[s] - dist_s[j]) + abs(dist_t[t] - dist_t[j]) - abs(dist_s[s] - dist_s[t])) // 2 + 1
    print(ans)

感想

たいへん、がんばった。
2ヶ月以上かけて行ったupsolve、すんごい快感であった…これだから競プロはやめられねえぜ

コンテスト後にやったこと

少し休憩を挟み、スポンサー企業さんの座談会が始まりました。 当時のわたしは会社員になることへの興味が非常に薄く「すごくわからない世界だ」と思っていました。 にも関わらず、興味を惹かれる話が、とても多かったです。

一番印象に残っているのはripsさんのお話で、RGB空間の話は好奇心をくすぐられまくりでした。やっぱり色のこと、すきなんだなあ。

その後、順位発表! 上位者の名前が呼ばれ、壇上へ向かうつよつよerたち。 とってもかっこよかったです。眩しく輝いていた…!

終わった後は、順番に懇親会会場へ移動。 寿司(2名分)やローストビーフやケーキやサラダやなんかおいしい抹茶色の物体などを食べました。ぱくぱくもぐもぐ!

マイクロソフトの方々と高校生たちかな?が作っていたペットボトルの塔が凄すぎた。共同制作…!

その後のしゃぶしゃぶ会に、金銭的理由などで参加できない高校生たちと「次はマクドナルドでオフ会開催しようね!!」という謎約束を残し、わたしは秋葉原へ。
これはちゃんと叶えたい約束だが、マックって予約?できるのかな。
できなかったらサイゼにするね!

コンテスト後のさらに後にやったこと

女子部でしゃぶしゃぶオフ会を開催!ぱんぱかぱーん!
開催するに至ったきっかけは、今回CodeQUEENに出場できなかった(しなかった)人も含めて、交流の機会にしたかったからです。ぶり、便乗だぁいすき!

CodeQUEENと直接関係ない話にはなりますが、わたしが競プロ界隈で「動く」瞬間の共通点は 機会を得るのが難しい人のために、機会をつくる だと気付きました。
おそらく、自分の教育機会の未獲得や、学生時代の無力さなどが根底にあるとは思います(そちらについてもしご興味がある方は、入茶記事不登校記事を読んでいただけると…!)。

自覚したからとてセーブするつもりはなく、また突拍子もないことを わはは! と踊り回りながらやるんだろうな。その時は楽しく見守ったり、参加したりなどしてやってください。

しゃぶしゃぶで心も体も満たされたあと、ももはらさんがてんぷらさんを待つ間、時間ができた!という、うれしい(?)トラブルが発生。 その場のノリで2次会を開催。10人以上引き連れてカラオケに行きました。

当時、kemunikuくん主催の異常精進サーバー1期が走っていたため、お歌の順番が来るまでに茶diffをupsolve。その様子を隣で見ていたかえでさんに「人が競プロやっているのをこうやって見るの、新鮮で楽しい!」と喜んでいただき、ハピネスぶりになりました。

ちゃんと学生時代を過ごしていたら、10名以上の女子でカラオケに来る、なんて、当たり前だったのだろうか。
そんな当たり前を、この歳になってからぬるっと叶えられた事実にほろりと、いろんな人へのありがとうを胸に、ちゃんとおうちにかえりました。

その夜見た夢は、ひみつです。

まとめ

こちらのツイートで書いたことが我ながらよかったので、そのまま引用します。

主催のkenkooooさん、スポンサーの皆様方、素敵な機会をありがとうございました!

懇親会でkenkooooさんが「ひとりで全部決断しなきゃなので大変でした。会場もそうだし、懇親会のメニューはお寿司で喜んでくれるかなあ、とか」と、運営側のお話を聞かせていただき本当に頭が上がりませんでした。 マイノリティをピックアップするというのは本当に勇気と労力がいることで、話題になる分の何倍も、配慮が必要だということ、改めて思い出させていただきました。

だからこそ、プログラマー、競プロerの女性がこのままマイノリティでいてはいけない、と思いました
今日させていただいた経験を、他の女性競プロerもできるように。BFSの波紋の力!!のように広げていき、女性人口が増えに増え、自分のようなレート弱者が決勝にあっさり進めない世界線を作るお手伝いをしたい。と、女子部で企画した二次会帰りに、じんわり思いました。
女子部はわたしが「立てただけ…」の、活動がないふわふわしたものでしたが、Code Queenをきっかけに、ちゃんと活動することができました。会場でも「あるとは聞いてて〜」と話しかけていただき、DM送りまくるマンになって気付きました。「本当に立てただけだった」と。

二次会や三次会で、主催が自分に移ってから「みんな、楽しんでくれているだろうか。ひとりでいる人は、このままにしておいてよいのか、それとも話しかけて他のグループに混ぜたほうがよいのだろうか」など、必死に考えて話していました
正直全員を満足させられた自信はなくて、名前が飛んでしまったりなど失礼なことしてしまったり、1人の時間を長引かせ追い詰めてしまったのでは、など、憶測の後悔も含む反省点はたくさん、あります。 裏でまた何かを言われる自信もたくさんあります。でも

私は確かに、競プロで人生が明るくなりました

なので、ぬるく長く、少しでもいいから、女性競プロerのために何か続けていきたい。でも、こういうのって何が正解かわからないから、失敗や試行錯誤しながら、女子部の方々に力を借りながら、なんかどうにかうまく、ためになりたい!と!深く深く思いました

本当に、すてきな1日をありがとうございましたと、関わってくれてるみなさま、これからもよろしくお願いします

いつか競プロ女子部鯖が、オープンで活動できる日が来ますように。いつでも入部希望DMお待ちしています!

体は女性
心はどちらでもなく
声が両生類のぶりより🐟

最後まで読んでいただき、ありがとうございました!

船上競プロのしおり

結論から言うとおすすめしません✌️

 

 

あらすじ

2023/9/2(土)

茶コーダーは小樽〜新潟間を走るフェリー「らべんだあ」にて、ABCへの出場を試みた。

 

f:id:burioden:20230904235829j:image
f:id:burioden:20230904235825j:image

 

🐟「個室だし!船内WiFi(1日5回 × 30分 = 150分)あるし!いけるやろ!!」

 

と、iPhoneの右上を見ると、出航5分ですでにLTEが0(4Gは3本ほど)

 

🐟「4Gはなんとか…陸が近ければいけ…るやろ!どこをどれくらいに通るのじゃ?」


f:id:burioden:20230904235822j:image

 

🐟「いけそう」

 

 

…その後、仮眠をとり、無謀にもRated参加をしたのであった……

 

さて、午後10時40分、北海道は函館の沖合にてコンテスト終了

結果発表〜!!!!!

 

f:id:burioden:20230905000308j:image

f:id:burioden:20230905000313j:image

 

そりゃあそう!!

なのだが、具体的な敗因が4つあったので、記念にメモしておくよ。

 

やると良いこと

 

その1.陸側の部屋を取ろう

海側の部屋はLTEも4Gもほぼ入らなく、船上WiFiは陸からのLTEの電波を分配するだけの装置?らしい。つまり、己のLTEが入るなら、そっちのがつよい。陸側の部屋をとれば、なんとかLTEか4Gデザリングで出られる(全体的に4Gのが強かった)

わたしの宿泊した海側の個室は電波ダメすぎたので、ロビー陸側にてコンテストに出たよ。

 

 

その2.ojt(できればacc)を導入しておこう

開始から5分間、アクセスががんばれなくてページが開けず、問題文がわからなかった…

ojtでA問題のテストケースだけは落とせていたので、エスパーしようとがんばっていた5分間であった。あとから考えると、accで全問落としておけば、B以降も問題文ダウンロードの間に入出力エスパーができる(かも)。

 

 

その3.できるだけ歩き回ろう

個人差はあるが、5分間画面を見つめているだけで激しく酔ってしまうぞ!

考察タイムなど、コーディングしなくてよいときは、なるべく歩いたりして三半規管パワーをとっておこう。すべてがゆらゆらになってC問題すら解けなくなるぞ…

 

 

その4.消灯時間を確認しよう

あれは、C問題を考察している時じゃった…考えるのに夢中になっていたわたしに突如襲いかかった22時の暗闇……そう、「消灯時間」

あまりにびっくりして、C問題の考察がすべて吹っ飛んだ!

陸側個室ならば、もちろんこれも回避できるぞ…

 

 

とはいえ

フェリーでの移動自体はかなりおすすめ!

前回は青函フェリーにて青森〜函館間を移動し、その時はずっと電波ありがとう状態だったため、悠々自適に船上精進ができた!

 

f:id:burioden:20230905002055j:image

 

※写真を撮り忘れていたので、代わりに船上カップヌードル

 

寝ている間に移動できる、宿泊費と移動費を兼ねられるのはとてもお得なのと、船上露天風呂がかなり最高。らべんだあには、サウナもあるし!

 

そして、23時ごろから本格的にインターネットグッバイになったのも、個人的によい経験であった。

いつもは手が寂しくなったらXやらなんやらを開く、の代わりに、本を開いたり、ストレッチをしたりなどの感覚が新鮮で、少しずつ生活に取り入れたいなあとなった。

フリーランスを長くやっていると、レスの速さ=信頼の高さ、を実感してしまっており、普段の即レス癖がやばいのです…

 

その経験が活きたのか、いまこのよくわからない記事を書きながらも、わたしは有酸素運動をしている。えらい!えらすぎる!1000000007点!!

 

以上、ひさしぶりになんのためにもならない記事でした。

ご覧いただき、ありがとうございました!

ABC310振り返り

ABCの3完!ペナ量産回!フハハハ!!
でも、klu大学さんのおかげで緑パフォでたよありがとう…!!!たなぼた!!!!



A問題

atcoder.jp

問題概要

P円のドリンク飲みたい!

  • 方法その1:単品購入 P円
  • 方法その2:セット購入 Q円 + 料理の値段(セットにする料理はN種類の中から1つ自由に選べる)

いっちゃん安い方法で飲みたい!

考察

  • P円(単品) と Q円 + 料理リストの中でいちばん安い値段 (セット)の小さい方を出力しよう

コード

# 入力
n, p, q = map(int, input().split())
a = list(map(int, input().split()))

# セット価格
set_p = q + min(a)

# 単品とセット価格を比べ、安い方を出力
print(min(p, set_p))

感想

本番は慌てて変なコード書いたけど、方針はいっしょ
シンプルに考えよう、シンプルに…(念)



B問題

atcoder.jp

問題概要

商品Aに対しての、上位互換商品Bがあるか調べたいよ
定義は3つあるよ

  • 商品Aと商品Bの値段を比べたとき、商品Bは同価格または安い
  • 商品Aにある機能を、商品Bは全て持っている
  • 商品Aより商品Bは安い、または、商品Aより商品Bは機能が多い

考察

  • 制約がN≦100なので、O(N2) = 104 で、二重ループの全探索が余裕!
  • 配列内を上手に分割してあげよう
  • 条件②については、部分集合(AはBの一部か)を判定してあげよう

コード

# 入力
n, m = map(int, input().split())
g = [list(map(int, input().split())) for _ in range(n)]

for a in range(n):
    for b in range(n):
        
        price_a = g[a][0] # 商品Aの値段
        price_b = g[b][0] # 商品Bの値段
        func_a = g[a][1] # 商品Aの機能数
        func_b = g[b][1] # 商品Bの機能数
        func_a_set = set(g[a][2:]) # 商品Aの機能の種類
        func_b_set = set(g[b][2:]) # 商品Bの機能の種類
        
        # 条件① 商品Aと商品Bの値段を比べたとき、商品Bは同価格または安い
        if price_a >= price_b:
            # 条件②商品Aにある機能を、商品Bは全て持っている(部分集合判定)
            if func_a_set.issubset(func_b_set):
                # 条件③商品Aより商品Bは安い、または、商品Aより商品Bは機能が多い
                if func_a < func_b or price_a > price_b:
                    # 全て当てはまったら即座にYesで終了
                    exit(print('Yes'))

# 当てはまるものがなかったらNo
print('No')

感想

公式解説、たしかにすごかった!すごかった!!
なので、わたしは分かりやすさ重視で書いてみた!!! あれ、M、使わなかったな…



C問題

atcoder.jp

問題概要

N個の文字列が入っている、配列Aがあるよ。
abc と、反転した cba は同じ種類と見做すよ。
文字列は、何種類ある?

考察

  • a, ab, ba の3つの文字列がある場合、答えは 2 種類になる

他の文字列と比較して解く

  • 配列Aから、同じ種類のものを判定し、引く作戦
  • カウント用変数 cnt を用意
  • 各文字列について、反転したものと同じものがAの中にあるかつ、反転したものが自分自身ではない場合、cnt += 1
    • a は、反転したもの(a)と同じものがAの中にある、かつ、反転したもの(a)が自分自身なので、カウントしない
    • ab は、反転したもの(ba)と同じものがAの中にある(ba) かつ、反転したもの(ba)が自分自身(ab)ではないので、カウントを+1する
    • ba は、反転したもの(ab)と同じものがAの中にある(ab) かつ、反転したもの(ab)が自分自身(ba)ではないので、カウントを+1する
  • 重複でカウントするため、cntをわる2する
  • 配列Aの長さから cnt を引き算

バグらせ狂ったので、本番はACしたけど、他の方法を学ぶどん!



正規化して解く

  • 正規化とは:データを扱いやすいようにしてあげること!主に重複削除のことを指す
  • 今回『どんな文字列』が何種類ある?とは問われていないので、文字列自体はどうでもいい(?!)
  • ab ab ba は同じとみなすので、全て辞書昇順(または降順)で揃え ab ab ab に揃えたら、かんたんに重複を削除できる!
  • ab と、反転した ba を比較して、大きい方(または小さい方)を、setに入れてあげれば重複削除ができる!!(すごい)

コード 他の文字列と比較

# 入力
n = int(input())
# setで入力して、普通の重複は削除しておく
a = set(input() for _ in range(n))

# 種類数(この時点で、反転は別種類と判断している)
ans = len(a)
cnt = 0

for i in a:
    # iを反転したものがaの中にあるかつ、iを反転したものとiが不一致なら
    if i[::-1] in a and i[::-1] != i:
        cnt += 1

# 重複削除
cnt //= 2
print(ans - cnt)

コード 正規化

# 入力
n = int(input())
a = [input() for _ in range(n)]

# 答え格納用set 重複は自動的に削除される
c = set()

for i in a:
    # aの中の各iについて
    # 自分自身と、反転したものを比較。大きい方をcへ入れる
    c.add(max(i, i[::-1]))

# cの要素数を出力
print(len(c))

感想

正規表現と正規化を勘違いしてたので、ついでに両方学んだ!
用語を知るだけじゃなくて、理解するができてよかったあ

DとEはわたしにはまだはやすぎた腐ってやがる!になるので、あきらめた!!またね!!!



来週のburiodenは

女子大生とおいしいパンケーキして、お昼寝したあとに、ABCやるぞお!!うおおおおおお!!!!!!

ABC309振り返り

ABCDの4完!Cのくだらない1ペナうわあああああ
3週間連続出られてる&上がってる!もうすこしで緑パフォだった。次こそは!
今回は反省点がしっかりある。特に…アクアパッツァについて……



A問題

atcoder.jp

問題概要

1 2 3
4 5 6
7 8 9

この内2つの数字がa, bとして与えられるので 左右に 隣接しているか判定してね
制約でa < bであることは保証されているよ

考察

  • 隣だから a + 1 == b かどうか、か
  • でも、aが右端の時だけはだめだな

コード

#入力
a, b = map(int, input().split())

if a + 1 == b and a % 3 != 0:
    print('Yes')
else:
    print('No')

感想

ペナ率45.45%はすごくびっくりした
ABはやときで誤読しづらいの、速読できるからと、テキストコミュニケーションに慣れているから…?
本番では条件を if a == 3 or a == 6 or a == 9: って書きながら「あ…余剰で書いた方がはや…い…まあ…いいか…」と突き進んだのがよい思い出



B問題

atcoder.jp

問題概要

1と0からなるN × Nのグリッドの、外側だけを時計回りに1ずらして回転して出力してね

考察

  • 賢く解くのは無理なので、時間かけていいからしっかりと条件を整理しよう
  • 真ん中のことは考えなくてよいので i = 0 j = 0 i = n - 1 j = n - 1のそれぞれについて条件を整理
  • i = 0:1行目の
    • j = 0: 1列目は、1行下を出力
    • それ以外は、1列前(左側)を出力
  • i = n - 1 :最終行の
    • j = n - 1 :最終列は、1行上を出力
    • それ以外は、1列後(右側)を出力
  • j = 0 :それ以外の1列目は、1行下を出力
  • j = n - 1 :それ以外の最終列は、1行前を出力
  • それ以外は、内側なので、そのまま出力

コード

#入力
n = int(input())
# 文字列で受け取る
g = [input() for _ in range(n)]

for i in range(n):
    # 1行分を格納する文字列
    inner = ''
    # 列のループを回し、各条件チェック
    for j in range(n):
        if i == 0:
            if j == 0:
                inner += g[i + 1][j]
            else:
                inner += g[i][j - 1]
        elif i == n - 1:
            if j == n - 1:
                inner += g[i - 1][j]
            else:
                inner += g[i][j + 1]
        elif j == 0:
            inner += g[i + 1][j]
        elif j == n - 1:
            inner += g[i - 1][j]
        else:
            inner += g[i][j]
    # 1行分のループが終わったら出力
    print(inner)

感想

条件整理をコードで書いてしまって時間かかった(なぜ)
書き写すときに気付いて修正するの手間だったので、次から日本語でやる
賢く解くのではなく、丁寧な場合わけをしたの、すごくえらい
N <= 100 でも文字列追加はこわくてPython3で投げるのも とてもえらい

C問題

atcoder.jp

問題概要

お薬いっぱい(N種類)処方されたよ…今日から飲んでいくよ…
それぞれのお薬について、今日からA日間、B錠飲むよ。
1日に飲む量がK錠以下になる日を知りたいよ…健康イズ大事

考察

  • めっちゃ飲むやん
  • とりあえず表にまとめてみた。日数が経つごとに、絶対に薬は減っていく。よい
  • A日目は言い換えると「量が減る前日」なので、K錠以下になる「X日目」はA + 1日目になる
  • 例外として、1日目で既にK錠以下だった場合は、1日目だよ〜を吐いて終了
  • ソートしてもOKだなあ
  • Bを全て合計したものから、各Bを引いていけば、K錠以下になるタイミングが掴めそう

コード

#入力
n, k = map(int, input().split())
d = []

# bの合計値 1日目に飲む全ての量
s = 0
for _ in range(n):
    a, b = map(int, input().split())
    s += b
    d.append([a, b])

# 日数と錠数を、日数を基準にソート
d.sort()

# 初日(全てを飲む日)k錠以下だったら、1日目で達成
if s <= k:
    exit(print(1))
    
for i in range(n):
    # 全体の合計から、各日の錠数を減らしたあと
    s -= d[i][1]
    # k錠以下だったら、翌日に達成
    if s <= k:
        exit(print(d[i][0] + 1))

感想

「1日目で減ったときK以下になった場合は、2日目に達成、が例外だな」という謎理論をかまし、その場合の出力を2と設定し1ペナ
「何日間続けて飲むか」の最小が1であることなど保証されていないので…
速攻気付けたのえらいけど、しょーもなさすぎた。条件整理をもう少し俯瞰する必要がある



D問題

atcoder.jp

問題概要

分かれた状態になっている2つのグラフが与えられる。
2つを繋げ、頂点番号1〜最後から辿る際、辺をたくさん通りたい。
最適な繋ぎ方をしたら、最大でいくつの辺を通れるだろうか。

考察

  • 制約をめちゃくちゃ見る(えらい)そしてありとあらゆるパターンを描く(えらい)
  • グラフ①の1〜最後の頂点と、グラフ②の最後〜最初の頂点の 最大の距離 を調べ、合計し、繋げる辺としてさらに +1 してあげるとよさそう
  • (冷蔵庫にしまい忘れたアクアパッツァが目に入る おいしそう…ぱくぱくもぐもぐ!8分経過)
  • ふう!まんぞく!どうせDは時間かかるからな!さて本気出すぞ〜BFSの関数をいじるとよさそう
  • (コピペにて瞬殺 あれ?)

コード

# BFSで使用するqueのインポート
import collections

# 入力
n1, n2, m = map(int, input().split())
g = [[] for _ in range(n1 + n2)]
# 隣接リストを作り、どこがどこと繋がっているのかを保管
# (0-indexedなので、以後全て-1)
for _ in range(m):
    a, b = map(int,input().split())
    g[a - 1].append(b - 1)
    g[b - 1].append(a - 1)

# xからyへの距離を測るBFS
def bfs_dist(x, y):
    d = [-1 for _ in range(y)]
    max_d = 0

    que = collections.deque()
    que.append(x)
    d[x] = 0

    while que:
        p = que.popleft()
        z = d[p] + 1
        for i in g[p]:
            if d[i] != -1:
                continue
            que.append(i)
            d[i] = z
            max_d = max(max_d, z)
    
    return max_d

# グラフ①0 〜 n1までと、グラフ②n1 + n2 - 1から他頂点までの最大距離 + 1
# グラフ②について、最大のループ数を確保したいのでyがn1 + n2になっているが、結局グラフ②が保持している頂点だけを見るのでOK
print(bfs_dist(0, n1) + bfs_dist(n1 + n2 - 1, n1 + n2) + 1)

感想

テストケース、めちゃ多くてどきどきした
考察をしっかりしたもの、ちゃんと1発で通るんだなあ(それはそう)
アクアパッツァぱくぱくタイムがなかったら8分くらいははやかった…



来週のburiodenは

録音したCDがディスクユニオン各店頭に並ぶので、ありがとうよろしくお願いします!する旅をした後、たぶん路上ライブして、ABCに出るぞい
今週中に灰diffを埋めて、茶diffしか解けない世界線に自分を強制連行したい所存

ABC308振り返り

ABDの3完!Cは気合の10ペナ!
ひさしぶりにめっちゃしっかり復習したから書く〜



A問題

atcoder.jp

問題概要

8個の整数たち(配列S)が

  • 昇順
  • ぜんぶ100〜675
  • ぜんぶ25の倍数

この3つの条件に全て当てはまっていたらYes、一つでも違ったらNoと出力してね

考察

条件がいくつかあって、ひとつでもちがうよ…なら速攻No系は、コードもおなじおきもちで書いてあげると速く解けます。
どういうことかというと「全部あってたらYes」ではなく「ひとつでも間違ったらNo」で、式もnotやFalseベースで書いてあげます。
やり方に関しては、即効No吐いておわりにしてもよいし、フラグ管理してもよい。告白だったらとてもかなしい考え方だ…

各条件の判定について

  • 神目線で、配列全体を上から見下ろし、全体で判定した方が楽か
  • ダンゴムシ目線で、要素ひとつひとつみていかないと、わからないことなのか

を、整理していきます。

①昇順(広義単調増加 S1 ≦S2≦S3...)か
・SをソートしたTという配列を新たに作り、一致するか確かめる

②ぜんぶ100〜675か
・ひとつずつ確かめる。しかたない。人生そういう時の方が多い

③ぜんぶ25の倍数か
・ひとつずつ25で割ったあまりが0か確かめる
sum(S) % 25 == 0 か確かめる これは嘘解法でした、失礼しました の、好きな方を、①か②と同時に判定してあげるとよいです。

コード 即座にNo

#入力
s = list(map(int, input().split()))
# sを昇順ソートしたtをつくる
t = sorted(s)

# sと、sを昇順ソートしたtが不一致ならNo
if s != t:
    exit(print('No'))

for i in s:
    # 25で割り切れないならNo
    if i % 25 != 0:
        exit(print('No'))
    # 100未満だったり、675より上ならNo
    elif 100 > i or i > 675:
        exit(print('No'))

# No条件にひっかからなかったらYes
print('Yes')

コード フラグで管理

#入力
s = list(map(int, input().split()))
# sを昇順ソートしたtをつくる
t = sorted(s)

# 条件にすべて合ってると仮定してはじめる(性善説!)
flg = True

# sと、sを昇順ソートしたtが不一致、または全体が25の倍数でなければNo は 嘘解法ですが通ります…
if s != t or sum(s) % 25 != 0:
    flg = False

for i in s:
    # 100未満だったり、675より上ならNo
    if 100 > i or i > 675:
        flg = False

# No条件にひっかからずflgがTrueのままならYes そうでなければNo
print('Yes' if flg else 'No')

感想

自己肯定感が高く、他人に対しても全肯定癖があるため、反対にするのに時間がかかった。生き方も含め反省。



B問題

atcoder.jp

問題概要

お寿司やさんお会計問題です。

  • N皿食べました
  • 配列Cに、N皿分のお皿の色が書いてあります
  • 配列Dに、M種類のお皿の色が書いてあります
  • 配列Pに、M + 1 種類のお皿の値段が書いてあります。配列Cには、配列Dにない色のお皿も含まれていそうで、そういう時はP[0]で統一価格とします

合計いくら食べたかな…やべえ……

考察

こういう現実にありそうな設定のものは、問題文はさくっと読み、サンプルの方を熟読すると速いです。
実際、問題文読んでると「なんでDとPともにM種類なのにPの長さが + 1、おん???」となりがち…
せっかく順番対応してくれているので

  • 色と値段を辞書にして、値段表みたいにする作戦

を先に考えましたが、実装がパッと出てこなかったので、本番は

  • インデックスをとる作戦

にしました。
Dの長さがM、Pの長さがM + 1、Pの0項目が邪魔だなあ…ならば 取って仕舞えばいいのです

コード インデックスとる

# 入力コーナー
n, m = map(int, input().split())
c = list(input().split())
d = list(input().split())
p = list(map(int, input().split()))

# 合計出す用ans
ans = 0
# 配列pの最初の要素(その他の値段)
z = p.pop(0)

# 食べた皿たちを順番に見ていく
for i in c:
    # 皿色リストdに存在していたら、値段表配列pから同じ位置の値段をansに足す
    if i in d:
        ans += p[d.index(i)]
    # 皿色リストdに存在してなかったら、zを足す
    else:
        ans += z

print(ans)

コード 値段表

# 入力コーナー
n, m = map(int, input().split())
c = list(input().split())
d = list(input().split())
p = list(map(int, input().split()))

# 合計出す用ans
ans = 0
# 配列pの最初の要素(その他の値段)
z = p.pop(0)

# 値段表作成 dとpをzipして辞書を作成
price_list = {i: j for i, j in zip(d, p)}

# 食べた皿たちを順番に見ていく
for i in c:
    # 値段表に存在していれば、ansに足す
    if i in d:
        ans += price_list[i]
    # 存在してなかったら、zを足す
    else:
        ans += z

print(ans)

感想

既存の2配列から1つの辞書を作るの、こうやって書くんだ!へえ!
zipすごい!!



C問題

atcoder.jp

問題概要

  • N人がコイントスをしました。コイントスとは、何回かコインを投げ、表が出た確率を競うゲームだよ
  • コインの表が出た回数がA、裏が出た回数がBだよ
  • 表が出た確率は、表が出た回数 A ➗ 総回数(A + B)で求められるよ
  • 確率が高い順に人1〜Nの番号を出力してね。ただし、同点の人がいたら、番号が小さい順に出力してね。

考察

こういうのがCに出た場合、愚直にA / (A + B)をすると絶対に死にます。戒めえ〜!!!!(本番解けなかったので)

どうして死ぬか、というと 小数同士の比較は、小数にする時点で0.1以降が壊れるので正しくない (理由について、詳しくは浮動小数点でググってね)からです。

解決策としては3つ

  • 式変形をする
    もちろん、まず式変形を考えました。
    しかし、わたしはまだ算数1年生で、不等式の式変形をする公式解説のような発想など出るわけもなく…ちーん。詳しくは、おしゃれいけめんnok0さんの公式解説を読んでください。

  • A / (A + B) の分子Aにすっげーでっけー数(10100)をかけておき、intのまま比較できるようにする(きりさん解説) 例えば、0.3を30%という表記に直すとき100をかけるように、とにかくでっかい数字にしておくと、Pythonはintの有効桁数がでっかいから大丈夫だよ!というおはなしです。

  • decimalを使用し、壊れない小数として扱う

ちなみに、今回は分母になる(A + B)が1以上になる制約のため気にしないで良いですが、0を分母に持ってくる(0でわる)とREとなります。

ちなみにちなみに「片方は大きい順で、もう片方は小さい順で」という、一筋縄のソートでいけないやつは 小さい順にしたい方に、-1をかける という脳筋技をすると、ただのソートでいけるようになります👍
※逆でも良いです。つまり、大きい順にしたい方にマイナスをかける。こちらの方が、本問題では出力時に再びマイナスをかける手間と、降順ソートする手間が省けます。が、「小さい順にしたい方にマイナスをかけ、降順にする」の方がパッと感覚的に使いやすいので、わたしはそうしています。

例えば

  • [1, 2], [2, 5], [1, 3][2, 5], [1, 2], [1, 3] にしたい
  • 普通にソートすると [1, 2], [1, 3], [2, 5] になってしまう
  • ので、2項目に-1をかけて [1, -2], [2, -5], [1, -3] にしてから降順ソートすると
  • [2, -5], [1, -2], [1, -3] 🎉

あと…「何人め」の情報を入れてあげたい時は、入力forで使うiを利用してあげるとよきよきです!

コード int状態作戦

# 入力
n = int(input())

# 答え格納用配列
ans = []

# abの入力
for i in range(n):
    a, b = map(int, input().split())
    # ans配列にint状態の確率と、何人めかの情報を入れる。何人めか?は昇順にしたいのでマイナスにしている
    ans.append([a * 10 ** 100 // (a + b), -(i + 1)])

# ans配列全体を降順ソート
ans.sort(reverse=True)

# ansの2項目にマイナスをかけて正に戻しながら出力
print(*[-d for _, d in ans])

コード decimal作戦

# Decimalを使えるようにimport
from decimal import Decimal

# 入力
n = int(input())
ans = []

for i in range(n):
    # Decimalで受け取ると、壊れないで愚直のままいける
    a, b = map(Decimal, input().split())
    ans.append([a / (a + b), -(i + 1)])

ans.sort(reverse=True)

print(*[-d for _, d in ans])

感想

コイントスにおける成功ってなんだ」というのを調べるのに10分くらいかかった。ゲーム、もっと知っておくべきだ…を何回か思っている。真っ暗な青春を送るとこうなるよ!ぜひいっぱいあそんでね!!
小数について、めちゃくちゃ勉強と教訓になりました。ありがとうnok0さん!

D問題

atcoder.jp

問題概要

H行W列のグリッドに書いてある文字たちを、スタート(0, 0)から「s⇨n⇨u⇨k⇨e⇨s⇨u...」という順番で辿って、ゴール(h - 1, w - 1)に辿り着けるのか判定してね

考察

  • DFSまたはBFSして、h - 1とw - 1にたどり着いてたらOK、あとはぜんぶNoにしよう
  • snukeの判定は、剰余使って管理しよう

DFSとBFSについては、よい解説記事がたくさんあるので置いておき…そのうち自分でも書いてみようかな!

で、剰余(%)はとっても便利です。 たとえば、24時間表記を12時間表記にすることを考えてみませう。

  • 13 ⇨ 1
  • 24 ⇨ 0
  • 3 ⇨ 3

このとき、左側の数字に % 12 をしてあげることを考えると、数が0〜12の間で循環してくれるので、うれしくなれます!

これを利用して、5文字のsnukeをぐるぐる循環させてあげます。

コード DFS

import sys
sys.setrecursionlimit(10 ** 7)

# 入力
h, w = map(int,input().split())
g = [list(input()) for _ in range(h)]
s = 'snuke'

# xは0 ~ hの列番号, yは 0 ~ w の行番号, zはsnukeカウント用
def dfs(x, y, z):
    if not(0 <= x < h) or not(0 <= y < w) or g[x][y] != s[z % 5]:
        return
    if x == h - 1 and y == w - 1:
        exit(print("Yes"))
        
    dfs(x + 1, y, z + 1)
    dfs(x - 1, y, z + 1)
    dfs(x, y + 1, z + 1)
    dfs(x, y - 1, z + 1)

dfs(0, 0, 0)
print("No")

コード BFS

from collections import deque

h, w = map(int, input().split())
g = [input() for _ in range(h)]
s = 'snuke'

# 上下左右を調べるための距離配列
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

def bfs():
    que = deque()
    # 1項目は0 ~ hの列番号, 2項目は 0 ~ w の行番号, 3項目はsnukeカウント用
    que.append([0, 0, 1])
    # すでに行ったところを入れていく用
    gone = set()
    
    while que:
        v = que.popleft()
        x, y, z = v[0], v[1], v[2]
        
        if x == h - 1 and y == w - 1:
            exit(print('Yes'))
        
        elif (x, y) in gone:
            continue
        gone.add((x, y))

        for i in range(4):
            ny = x + dy[i]
            nx = y + dx[i]
            if 0 <= ny < h and 0 <= nx < w and g[ny][nx] == s[z % 5]:
                que.append([ny, nx, z + 1])

bfs()
print('No')

感想

BFSわかんねえ!なってたらainemさんとるかごんくんとぷせうどさんが助けてくれた…ありがとうございます!!
そして、もしや?となり、1文字めがsじゃなくても通ることを確認。ふええ

来週のburiodenは

静かな渓谷で神と釣りしてからABCにでます!自然ぱわあ!!