我、京大生ぞ

現役京大生の雑記。メインテーマは大学受験とプログラミングと英語と京大の日常

ことわざをプログラマっぽく言い換えてみた


こんにちは、京大生ブロガーのゲーテ(@goethe_kyodai)です。
 
 



コチラの記事が理系だけじゃなく文系にも好評だったので、ことわざをプログラマっぽく言い換えてみた というスピンオフ作品を作ってみました。


文系でもプログラミング未経験でも雰囲気で楽しめると思います!
 
 
目次

 
 



青は藍より出でて藍より青し


」って曖昧な表現で気になりません?


「青」と表現できる色って何種類もあるけどどれなんだよ!(カンニング竹山風ボイス)って思いません?


プログラマなら色をHTMLのカラーコードで言い換えたくなりません?なりますよね。


青 → この色 →HTMLのカラーコードで表すと #0000FF




青は藍より出でて藍より青し

#0000FFは藍より出でて藍より#0000FF



類題:縁の下の力持ち、朱に交われば赤くなる をプログラマっぽく言い換えよ。(解答は読者の演習課題とする。)
 
 

海千山千


コンピューターが10進数の千を理解できますか?できませんね。コンピューターが理解できるのは2進数のみです。プログラマーはまず最初にこのことを習うと思います。


千(1000)を2進数に直すと・・・・・・1111101000です。




海千山千

11111010001111101000


 
 
※イメージ
f:id:a86223990:20180614171140j:plain

終わり良ければ全て良し


終わり良ければすべて良し→正しい結果が出力できれば全て良い→返り値が正しければ、関数の中身にバグがあっても全て良し
 
  



終わり良ければ全て良し

返り値良ければ 関数にバグあっても良し


 
 

腐っても鯛


【本当に立派なものや良いものは、少しぐらい古くなってもそれなりの値打ちがあるものだ。】という意味のことわざです。


これってプログラマの世界で言えばなんでしょうか?そうですアレです。


難しく書きにくい。ライブラリも充実していない。にも関わらず、メモリ割り当ての柔軟さと実行速度から未だに需要があるあのプログラミング言語です。


そう、


C言語


です。
 
  



腐っても鯛

腐ってもC言語


 
 

口は災いの元


プログラマーでいう「災い」とは「バグ」です。


初心者が必ずハマるバグとは?そう、身に覚えのない「全角スペース」です。


プログラムっていうのは文字列以外基本半角で書きます。ソースコードに全角が混じってるとバグを吐くのです。


そこで厄介なのが「半角スペース」と「全角スペース」、「 」と「 」です。


目視でほぼ見分け不可能なので、エディター(プログラムを書くのに便利なツール)でデバックしますが、たいていのエディターでは見つけてくれません。


というわけで、見分けほぼ不可能なのに目で1行1行チェックする羽目になって、時間を溶かします。
 
  



口は災いの元

全角スペースバグの元


 
 
別解:マクロ(#define)はバグの元(C言語)、タブはバグの元(Python)

二度あることは三度ある


プログラムを書いてると、二度あるバグは三度あります。というか、N度あるバグはN+1度あります。プログラミングとは無限に出てくるバグとの戦いなのです。
 
  



二度あることは三度ある

二度あるバグは三度ある


 
 

塵も積もれば山となる


塵 → 誤差 と言い換えてみましょう。


無理数や無限小数などの「無限に続く数」(例:π = 3.14159265.....)はコンピュータでは扱えないので、必ず有限桁で打ち切る必要があります。その時に必ず出るのが誤差です。


物理シュミレーションや数値計算をプログラミングでやる人は、この誤差と戦うハメになります。


一つ一つ見れば本当にゴミのように小さい誤差でも、for分内で積み重なると、無視できないくらいのような大きな誤差になることがあって、気をつける必要があります。
 
  



塵も積もれば山となる

誤差も積もればバグとなる


 
 

似て非なるもの


プログラマー界隈で「似て非なるもの」代表といえば、Python2系Python3系です。


Pythonという言語はとても書きやすく、初心者でもバグの少ない言語です。かなり快適にプログラミングできますが、Python2系とPython3系の互換性(相互の関連)が全然ないのが、玉にキズです。


名前はほぼ一緒なのに、悲しいほど互換性がありません。初心者は「似てるし一緒だろwww」と思ってダウンロードしてみたら全然違うものでバグとの戦いに明け暮れた、なんてあるあるです。
 
 



似て非なるもの

Python2系Python3系


 
  

噓から出たまこと


噓から出たまこと → False から出た True → Falseを引数として、Trueを返す関数 → function( True ){ return False; }

function ( true ){
       return false;
}

 
 



噓から出たまこと

function( True ){ return False; }


 
  

ことわざのまとめ

 


#0000FFは藍より出でて藍より#0000FF

11111010001111101000

返り値良ければ 関数にバグあっても全て良し

腐ってもC言語

全角スペースバグの元

二度あるバグは三度ある

誤差も積もればバグとなる

Python2系Python3系

function( True ){ return False; }


 
 
追加してほしいことわざ、訂正、マジレスなどありましたらコメント欄までお願いします!
 
  
  
 

コンパイラ言語とインタプリタ言語の違いを誰でもわかるように説明する【図解】


こんにちは、京大生ブロガーのゲーテ(@goethe_kyodai)です。


プログラミング言語は大まかにコンパイラ言語インタプリタ言語の二つに分かれますが、コンパイラ言語とインタプリタ言語の違いをプログラミングと無縁な人でもわかるように説明します。


目次

 
 



まずコンピュータはどうやってプログラムを理解しているの?


コンピュータはどうやってこんなプログラム(ソースコード)を理解しているでしょうか?


図1
f:id:a86223990:20180611164357p:plain


コンピュータというのは、上の形のままプログラムを理解しているわけではありません。


コンピュータは原理的に0と1しか理解できないため、下のような0と1の羅列に直してもらわないと理解できません。


図2
f:id:a86223990:20180611165014p:plain


このコンピュータが理解できる0と1の羅列をマシン語(機械語とも言う)と言います。


プログラムを実行するとき、コンピュータに理解してもらうために、図1のソースコードを図2のようなマシン語に変換してやる必要があります。


f:id:a86223990:20180611171329j:plain


そしてコンパイラ言語とインタプリタ言語ではその変換の仕方に違いがある んです。

コンパイラ言語


コンパイラ言語は、実行にプログラムをまとめてマシン語に変換します。

 


f:id:a86223990:20180611172002j:plain


プログラムをマシン語に変換するのがコンパイラというソフトウェアです。変換することをコンパイルと言います。


ここでプログラミングをやる上で知っておきたいのは、コンパイラには種類があってその種類ごとに変換の方法が違う 、ということです。


変換の方法が違うので、同じソースコードでも、あるコンパイラを使ったらエラーが出ないのに、違うコンパイラを使ったらエラーが出ることがあるので注意です。


コンパイラ言語で有名なのはCC++です。古いですがCOBOLFORTRANもコンパイラ言語です。

インタプリタ言語


コンパイラ言語は、実行全部まとめてプログラムをマシン語に変換しますが、


インタプリタ言語は、実行一行ずつプログラムをマシン語に変換します。


f:id:a86223990:20180611174109j:plain


コンパイラ言語は実行前にマシン語に変換してしまうので、それと比べると、インタプリタ言語は実行時に変換という作業をしなければいけない分、コンパイラ言語より実行時間が遅いです。


インタプリタ言語は、一行一行実行するのでエラーも一行一行チェックできます。なので、一括変換されるコンパイラ言語よりバグ取りがしやすいです。


インタプリタ言語で有名なのはPerlPHPです。

Java


f:id:a86223990:20180611191606j:plain


ここは本題からちょっと逸れた、しかもちょっと込み入った話をします。飛ばしてもらってもかまいません


はじめに、「プログラミング言語は大まかにコンパイラ言語とインタプリタ言語に分かれる」と言いましたが、どちらにも属さないプログラミング言語Javaです。


Javaはコンパイラ言語とインタプリタ言語の両方の良いところを取ったみたいな言語です。


Javaでは、まずプログラムを橋渡し的なコードである、バイトコードというものに変換します。


そして仮想マシンという環境で、そのバイトコードをマシン語に変換し、実行します。


なんでこんなめんどくさいことをやるかというと、どんなプラットフォームでも速く実行できるようにするためです。


プラットフォームというのはなんなのでしょうか?


まず、プログラムはハードウェアOS上で実行されます。


そしてプラットフォームというのは、そのプログラムを実行するハードウェア(パソコン本体)やOS(WindowsやMac)のことです。


下図のように、ハードウェアとOSという土壌がないとプログラムは実行できません。


f:id:a86223990:20180611185228j:plain


コンパイラ言語では、同じことをやるプログラムを書くにしても、違うプラットフォーム(OS、ハードウェア)では、違うソースコードが必要です。


というのは、コンパイラはプラットフォームに合わせて作られてるからです。


プラットフォームAにはコンパイラAが、プラットフォームBにはコンパイラBが、というようにプラットフォームごとにコンパイラが違います。


そしてソースコードはコンパイラに合わせて書かなければいけないので、コンパイラが違えばソースコードも違うんです


f:id:a86223990:20180611191150j:plain


だから、コンパイラ言語ではプラットフォームごとに違うソースコードを用意しなきゃいけなくてめんどうです。


そこでJavaは、ソースコードをまずすべてのプラットフォームで通用するバイトコードに変換します。


そして、プラットフォームごとに仮想マシンでマシン語に一括変換することで、プラットフォームが違くても一種類のソースコードを用意すれば済むようにしてます。


f:id:a86223990:20180611195536j:plain


インタプリタ言語は、コンパイラを使うコンパイラ言語とは違って、プラットフォームに依存しないですが、さっき言ったように実行時間が遅いです。


インタプリタ言語の実行時間の遅さと、コンパイラ言語のプラットフォームへの依存性を同時に解消したのがJavaなのです。

理系の大学新入生が1・2年のうちに読むべき数学・物理の本&サイト【参考書】【理系京大生オススメ】


こんにちは、理系京大生ブロガーのゲーテ(@goethe_kyodai)です。


大学の数学・物理の授業は予備校の授業と違って、恐ろしくわかりづらいです!中には生徒のことを考えて分かりやすく授業する先生もいますが、1%もいないのが現実です。



そして大抵の人は授業で紹介されている参考書で自習しようとしますが、大抵難しくて読めません。


ダメな本ということでは決してなく、ガチで研究者を目指している人向けの良本が多いですが前提知識ゼロの初学者には向いていないことが多いです。


安心してください!世の中にはちゃんと分かりやすい大学の物理・数学の本がたくさんあります! 分からないのは単に情弱なだけなのです!


100冊以上の理工書を読んできた理系京大生のゲーテが、理系の大学新入生が1、2年うちに読むべき初学者向けの数学・物理の本・参考書・サイトを紹介します!厳密な議論に立ち入らず本質や流れを伝えることに特化した理工書を選びました!

目次

 
 



理系の大学新入生は『Amazon Student』に登録すべし!【毎月!本1冊無料!】

 

 

 
 
理系の大学新入生が理工書を読むなら、本がすべて10%OFF になる(AmazonStudent)にまず登録すべきです!

 
学生のうちに登録すれば半年間無料で年間費がたったの1900円になります!
 
 
1900円ならAmazonを何回か利用すれば送料分だけで元が取れます!
 
 
それだけじゃなくて他の特典もたくさんあるんですねー。

  • 当日お急ぎ便/お急ぎ便が使い放題
  • 本(コミック・雑誌を除く)が10%ポイント還元
  • 映画/ドラマが見放題!
  • 100万曲以上!音楽聴き放題!
  • Cloud Driveに無制限で写真の保存可能!
  • Prime Nowなら2時間で商品が到着!
  • Kindle本が毎月1冊無料
  • Amazonパントリーが利用可能
  • 無料ポイント(2000円分)GET!
  • 友達紹介で1,000円分のクーポンGET!

 
 
月に1冊無料は大きいですよね!4年間だと48冊、院を入れた6年間だと72冊無料 になっちゃうってことです。
 
  
 

数学ガールシリーズ



分厚いですがかなり読みやすいです。高校数学の知識は必要ですが、一冊2〜4時間でささっと読めてしまいます。


内容は理工学部の大学1〜3年で習うものなので決して簡単ではないですが、著者の結城 浩(@hyuki)さんが天才的に分かりやすく伝えてくれるので本当にスッと理解できます。


数学書にありがちな「定理→定理→・・・」ではなく、思考過程試行錯誤の跡をちゃんと見せてくれるので納得しやすいです。


群•環•体、イプシロンデルタ論法、同値関係、ペアノの公理、数理論理学などなど大学数学でつまずきやすいところが網羅されてます!初学者が間違いやすいポイントもまとまっています!


理系なら絶対に読むべきです!




飲茶さんの「哲学的な何か」シリーズ


飲茶さんの「哲学的な何か、あと数学とか」と「哲学的な何か、あと科学とか」はサイエンスの読み物です。


「科学とか」の方では相対性理論、エントロピー、量子力学、クオリアなど物理の話題が中心で、「数学とか」の方では、数学の歴史、ゲーデルの不完全性定理、公理と定理の違いなど数学の話題が中心です。


なかなか理解しにくい数学・物理の概念の説明がとても分かりやすいです。


この本で僕は万能だと思っていた科学や数学がいかに脆いか、その限界についてこの本で知ることができました。


大学で物理・数学を学ぶなら外せない視点をこの本で得ることができます!この本も理系なら必読です!


プロの数学 ―大学数学への入門コース



東大京大の大学入試問題を使って、その裏にある理論を紹介していく本。


線型性、基底、δ-ε論法、完備性、テイラー近似、リーマン球面などなど定義だけがよく分からない概念を優しい口調で高校数学の知識だけで説明してくれます。


高校数学から大学数学への橋渡しにぴったりの一冊です!

キャンパスゼミシリーズ



大学の数学は難しいですが、このキャンパスゼミで雰囲気だけ掴むとかなり理解がしやすくなります!


どれも高校数学の知識だけで1〜2時間もあれば読破できる手軽さです!


問題演習が豊富で基本的な問題を解けるようになるのがこの本の目的です。テスト前によくお世話になりました。理系大学生はテスト前にこの本を読むだけで試験勉強がだいぶ楽になります!


ちなみにたくさんシリーズがありますが、マセマはこの順番でやることをオススメしています!参考にしてください!


f:id:a86223990:20180319195447j:plain



直感的方法シリーズ


 

テーラー展開、固有値、フーリエ変換、正規分布、複素積分、中心極限理論、などなど理系大学生がつまづきがちなところを図で直感的に理解できます。


この直感的っていうのは本当で、数式や文の説明なしで図とグラフだけでイメージできるようになります。こんな本は他にないです!


数式でがっつり説明する本ではないのです。変に聞こえますが、普通の理工書の数式での説明で挫折してからこの本を読むとアハ体験ができてより理解が深まります!一回挫折してから読んでください!


「プログラミングのための」シリーズ


 
「プログラミングのための〜」とありますがプログラミングを知らなくても読める数学本です。


行列式や固有値、固有ベクトルなどの線形代数の基礎、中心極限定理、大数の法則などの確率・統計の基礎を図で直感的に理解できますし、問題演習でも理解を深めることもできます!


著者の例えが本質を突いていてとても分かりやすいです!


一通り薄く広く確率・統計と線形代数を学んでからこの本を読むと「あの定理とか定義ってこういうことだったんだな」と納得できます!

 

オススメの数学物理を学べるサイト


上でオススメした本を読んでも分からないところはあると思います。全てが分かりやすい万能な本はありません。あと理工書はそこそこ値段が高いです。そんな時はサイトに頼りましょう!


色んな本やサイトで知識を相互補完していくのが大学以降の勉強で大切です。ということで普段ゲーテがお世話になっている数学物理の解説サイトを紹介します。

EMANの物理学


EMANの物理学


図をたくさん使って説明していてとても分かりやすいです。扱う分野の幅がかなり広く、マニアックな分野もちゃんと説明があって飽きません。

物理のかぎしっぽ


hooktail.sub.jp


主に物理、それに必要な数学を図で分かりやすく説明してくれるサイトです。これもカバー範囲が広く、扱うのは初歩的な力学から計算物理学までと様々です。僕はベクトル解析のdivやrotやgradのイメージはこのサイトで掴みました。

ぴーすけ講座 経済数学(図でイメージを掴みやすい)


psuke.hungry.jp


経済数学とありますが、普通の理工系の数学とレベルは同じです。同じ分野を扱っています。こちらも図での説明が分かりやすくてちゃんと理解できます。陰関数の定理はこのサイトで完全に理解しました。

高校数学の美しい物語


mathtrain.jp


高校数学?大学数学じゃないじゃん!と思うかもしれませんが、大学数学もバリバリ扱っているサイトです。題名の通り、「高校生でもわかるように説明する」のがコンセプトなので高校数学の知識で理解できます。


もし高校数学の知識があやふやでも、高校数学ももちろん扱っていてしっかり同じサイト内でカバーできるので本当に便利です。

東工大Tomoki Kawahiraさんのサイト


www.math.titech.ac.jp


東工大大学院の数学科のTomoki Kawahiraさんの講義pdfを置いてるサイトです。


数学科と言えば難解な授業をやるイメージですが安心してください。この教授のpdfの「基礎の基礎」シリーズは初学者でも分かるようなクオリティです。よく分からなかった「位相空間」のイメージがこの教授のpdfで掴めました。

プログラミングが学べるサイト


理工系では授業でC言語かPythonをやると思います。研究でも使うでしょう。


プログラミングは指導者がいないとなかなか辛いものがあります。教授によってはほぼ放置で「自分で学べ」的な態度の人もいるでしょう。


プログラミングは本で学ぶより、サイトで実際に手を動かしつつ、時には人に聞きつつ学ぶのが一番効率がいいです。


プログラミングを学ぶのに最適な完全オンラインのサイトを紹介します!

PyQ



 
 

Python学習に特化したサイトです。入門から実務レベルまでスキルレベルを一気にあげることができます!今流行りの機械学習も学べます!


分からなかったところをプロに質問できる「メールサポート」システムがあるのでプログラミングを初めてやる人でも着実に理解できます!


こんなに内容が充実していて、月2980円から利用できます!ぶっちゃけ激安です!


 
PyQについてもっと知りたい方は、僕が1ヶ月体験してみた「PyQのレビュー記事」をご覧ください!
  
 

PyQのレビュー記事


PyQをレビューしてみた


 

Aidemy





こちらもPythonを学べるサイトです。入門からデータ分析、人工知能、機械学習、ブロックチェーンなどなど最新技術がこのAidemy一つで学べます!


今ならPython入門コースが無料なので今のうちに是非登録してください!


迷ってる人は無料ビデオカウンセリングで相談してもらうのがオススメです!


  

teratail





プログラミングの学習はバグとの戦いです。初心者が1人でバグを取るのはとても時間がかかるし非効率的です。バグが出たらteratailで質問しましょう。エンジニアたちがすぐあなたのバグを解決してくれます!返信もかなり速いです!



teratailについてもっと詳しく知りたい方は、「teratailを詳しくレビューしたコチラの記事」をご覧ください!実際利用して感じたメリット・デメリットを書いてます!
  
 
 
「プログラミングを効率よく学びたい」って人は人間がマンツーマンで手取り足取り教えてくれるプログラミングスクールに通うのがいいです!


でもプログラミングスクールって高いんですよね・・・安いところで7万くらい、高いところで60万とかします。


せっかくの高い買い物ですから、内容をよく吟味したいですよねー。
 
 
そこで、大手のプログラミングスクールは無料体験というのをやっているんです。実際に体験して雰囲気やカリキュラム、どのレベルまで到達できるかなどを知ることができるんですねー。無料でですよ!
  
  
僕が実際に体験したプログラミングスクールの体験談を「完全オンラインで無料体験できるオンラインスクールまとめ」と言う記事にまとめました!
   
  

  
     
 

プログラミングの勉強に必要な分野を図にまとめてみた【プログラマー必見】


こんにちは、京大生ブロガーのゲーテ(@goethe_kyodai)です。


皆さん、こんな悩みを抱えていませんか?

  • 情報系の高校or大学に入る予定で予習したいが何をどの順番で勉強したらいいのかわからない

  • もっと速くてメモリ消費の少ないプログラムを書きたいけど何をどの順番で勉強したらいいかわからない
  • プログラマーになりたいけどプログラミング以外に何をどの順番で勉強すればいいのかわからない

  • プログラマーで上を目指したいけど何をどの順番で勉強すればいいのかわからない


そんな人達のためにプログラミングの勉強に必要な分野をツリーの図にまとめてみました。


自分がプログラミング関係を勉強する中で


「これを理解するためにはこの分野をわかってなきゃいけない、あっこの分野を理解するためにはあの分野も理解しなきゃいけない、あっあれもこれも....」


とどんどん辿っていったのをまとめました。


これを見れば一発で勉強すべき勉強がわかる代物です!プログラマーは必見です!


目次

 
 



ツリー図


f:id:a86223990:20180618024713j:plain


「Aの勉強にBが必要」という関係を「A←B」で表してます。


「なぜこういう順序になるのか」を矢印の番号ごとに説明します。

1 プログラミング←アルゴリズムとデータ構造


ありとあらゆる実装にアルゴリズムとデータ構造の知識が必須です。


プログラミング関連の全ての技術にアルゴリズムとデータ構造が使われてると言っても過言ではないでしょう。


だから、技術の理解にはアルゴリズムとデータ構造の知識が必須といえます。理解できてないものは応用もできません。


最近はライブラリが充実してるからアルゴリズムとデータ構造は自分で実装しなくてもいいという人もいます。


ですが全てのアルゴリズムとデータ構造のライブラリがあるわけではないし、速くメモリ消費の少ないプログラムを書くなら絶対にマスターしなければなりません。


2 プログラミング←コンピュータアーキテクチャ


プログラムを実行するのはコンピュータです。


なので速くメモリ消費の少ないプログラムを書きたいなら、プログラムがコンピュータのCPUやメモリでどう実行されるのかをちゃんと把握してなければなりません。


メモリやCPUなどコンピューターのハードウェアの設計と構成を扱うのが「コンピュータアーキテクチャ」です。

3 プログラミング←データベース


プログラミングでWebサービスを作る場合膨大なデータを捌くことになります。そのデータをどう管理するかについての知識、つまりデータベースの知識が必要です。

4 プログラミング←ネットワーク


Webプログラミングではネットワークを意識する必要があります。


クライアントからどういうルールでどこをどう経由してサーバーにアクセスするのか、逆にサーバーからクライアントまでどういうルールでどこを経由してデータを送信するのか、一通り知っていれば早くトラブル解決できることがあります。


また、HTTPやTCP/IPなどのプロトコル(約束事)の知識はエンジニアなら必須です。


技術には流行り廃りがありますが、ネットワークの基礎は何十年も変わってません。ある前提に技術が構築される、インフラのようなものなので今後も廃って行かないものです。


ネットワークの勉強が無駄になることはないでしょう。

5 プログラミング←アセンブリ言語


多くのプログラミング言語ではプログラムはアセンブリ言語に変えられてからマシン語に変換されます。プログラミングの動作の真の理解にはアセンブリ言語を読めるようになる必要があります。


プログラムの速度をこれ以上ないレベルまで上げるためにアセンブリ言語でプログラムを書くこともあるそうです。

6 アルゴリズムとデータ構造←コンピュータアーキテクチャ


データ構造は記憶装置(メモリ、HDD、SDDなど)へのデータの格納の仕方と言えます。


記憶装置それぞれの読み書き速度や信頼性(HDDは読み書きが遅い、レジスタやメモリは速いなど)を知っていると、それぞれの特性を利用して速くメモリ消費の少ないプログラムが書けます。

7 グラフ理論←アルゴリズムとデータ構造


グラフの情報をどうやって記憶装置に格納するか、キューやスタック、ハッシュや木などのデータ構造の知識が必要です。


また、グラフ上の最短経路を求めるのにダイクストラ法やベルマンフォード法のようなアルゴリズムの知識が要ります。
 




 

8 コンピュータアーキテクチャ←論理学


コンピュータは0と1のみを扱います。1を真、0を偽とした真偽値をマスターするために論理学を勉強しておくといいです。

9 コンピュータアーキテクチャ←電気電子回路


コンピュータのハードウェアは電子回路からできてます。ハードウェアを根本から理解したいなら、電子回路の性質やコンデンサーなどの電子部品の知識が必要です。


電気電子回路を学ぶならこの本がオススメです。大学生向けですが、高校の教科書のようにわかりやすいです。


10 データベース←アルゴリズムとデータ構造


Bツリーなどのデータ構造の知識があると、読み書き速度やデータが静的(頻繁に挿入や削除をしない)か動的(頻繁に挿入や削除をする)かなどの用途に合わせてデータベースシステムを構築できます。


あるデータ構造で格納したデータの効率のいい探索アルゴリズムを知る必要もあるでしょう。

11 ネットワーク←グラフ理論


ネットワークはグラフで表します。


ルーティング(データをネットワーク上のどこを経由するかを決める方法)にグラフ理論で扱うアルゴリズムが必要です。


また、ネットワーク上の2地点の最短距離や、あるネットワークの最小全域木を求める時に、ダイクストラ法やプリム法などのグラフ理論のアルゴリズムの知識が必要になっていくので、ネットワークを勉強するならまずグラフ理論を勉強しとくべきでしょう。

12 グラフ理論←線形代数


グラフ理論ではグラフを隣接行列で表現します。行列を掛けたり色々するので、線形代数の知識が必要になってきます。

13 ネットワーク←情報理論


ネットワークは離れたところで「情報」のやりとりを可能にするものです。


そもそも「情報」とは何か、送れる情報量の限界はあるのか、あったらどの程度なのか、などの疑問に答えてくれるのが情報理論です。


14 グラフ理論←離散数学


グラフは連続値ではなく飛び飛びの値(離散値)を扱います。まさにその離散値を扱う離散数学を勉強しておくとグラフ理論の理解の助けになります。

15 電気電子回路←電磁気学


電気電子回路では、「電気」「電子」のような得体の知れない謎のものを前提にしています。


その正体を探るのが電磁気学です。


ただし勉強するなら難しいので覚悟が必要です。周りの理系大学生で、電磁気学が大学の理系科目の中で一番難しくてヒイヒイ言いながらやってるって人が何人もいます。

とっても大事なまとめ


正直に言ってプログラミングの勉強をするのにこれらすべてを学ぶ必要はないです(笑)。ていうか多すぎて無理だと思います。


ですが、プログラミングを生業とするなら、アルゴリズムとデータ構造、コンピュータアーキテクチャ、データベース、ネットワークの勉強は必須です。


これらをざっくりでも理解して頭の片隅にあると、プログラミングのいろんな技術の理解がかなりスムーズにできるからです。


あと人工知能や機械学習が大事になってくるこれからの時代は、それらの基礎となる線形代数も必須になってくるかもしれません。


正直、線形代数の勉強は本当に面白くないですが(同級生や教授含め、面白いと言っている人見たことない)、応用範囲がゴビ砂漠のように広いので勉強しておいて損はないです。


アルゴリズムとデータ構造、コンピュータアーキテクチャ、データベース、ネットワークを完全に深く理解したい人だけ、アセンブリ言語、論理学、電気電子回路、グラフ理論、情報理論、電磁気学、離散数学、線形代数を勉強するといいでしょう。


自分で紹介しといてなんですが、論理学や電磁気学まで掘り下げるのはやり過ぎな気がしますが(笑)。
 

 


 
 

2018年の京大数学をプログラミング(Python、Sympy)で解いてみた


こんにちは、現役京大生ブロガーのゲーテ(@goethe_kyodai)です。


普通に解いても面白くないのでプログラミング(Python)で2018年の理系の京大数学を解いてみました


プログラミングで解くことに重きを置き、厳密な議論は飛ばしていて模範解答とは程遠い解答となっているので高校生のみんなは参考にしないように。


使用言語:Python2系
使用ライブラリ:Sympy,Numpy,Math,matplotlib


Sympyの使い方はこちらを参考にしました。



はてなブログにコードを埋め込むのはこちらを参考にしました。


はてなブログにコードを埋め込む


http://www.tsubasa-note.blog/entry/source-code-highlighting/

 

目次

 
 



問題1

f:id:a86223990:20180310142205p:plain

(1)

C_1C_2からyを消去して整理して、

(b - a)x^2 - 2bx + b + c ・・・(1)

を得る。

上式の判別式をdiscriminant()で求めると、

 D = b^2 - (b-a)(b+c)

となる。

これをsolve()でbについて解くと、

b = \frac{ac}{c-a}

となる。

これをsubs()で(1)に代入してsolve()でxについて解くと、

x = \frac{c}{a}

を得る。

これをy = ax^2にsubs()で代入して、

t = \frac{c^2}{a}

を得る。

これらが答えの接点の座標である。

まとめると答えは

(\frac{c}{a}, \frac{c^2}{a})


(2)

まず先ほど求めた接点を(x,y) =(\frac{c}{a}, \frac{c^2}{a}) と置きます。

そしてsolve()でこれらの連立方程式をx、yについて解くと、

(a,c) = (\frac{y}{x^2}, \frac{y}{x})

となります。

これを条件(1)の不等式を等式に置き換えた、1 + c^2 -2aにsubs()で代入してsolve()でyについて解くと、

y = -\sqrt(-x^2 + 1) + 1 , \sqrt(-x^2 + 1) + 1

を得られます。

このyと閉区間 [-1,1] の範囲のxを使って、matplotlibで図示したのが下です。

f:id:a86223990:20180310175749p:plain

本来の条件(1)は不等式なので上図の円に囲まれた部分が答えです。(本来はa,b,cの条件から除外する点があるがめんどくさいので省略)


問題2

f:id:a86223990:20180310142250p:plain


f(n) = n^3 - 7*n + 9と置きます。

因数分解できなさそうなので代入して構造を調べました。

その前に整数nじゃ範囲が広すぎるので、f(n)が素数になり得るnの範囲を調べておきましょう。

g(x) = x^3 - 7*x + 9と置きます。

これをmatplotlibのpyplotで図示すると下のようになります。

f:id:a86223990:20180310153334p:plain

見た感じg(x) > 0となるのはx \geqq -3ですね。これで調べる範囲をn \geqq -3に限定できました。

では実際に代入して素数かどうかの判定をとりあえずn = -3 ~ 20 までしてきます。
プログラムで実際に代入した結果がこちら↓

n = -3,f(n) = 3で、「f(n)が素数である」はTrue
n = -2,f(n) = 15で、「f(n)が素数である」はFalse
n = -1,f(n) = 15で、「f(n)が素数である」はFalse
n = 0,f(n) = 9で、「f(n)が素数である」はFalse
n = 1,f(n) = 3で、「f(n)が素数である」はTrue
n = 2,f(n) = 3で、「f(n)が素数である」はTrue
n = 3,f(n) = 15で、「f(n)が素数である」はFalse
n = 4,f(n) = 45で、「f(n)が素数である」はFalse
n = 5,f(n) = 99で、「f(n)が素数である」はFalse
n = 6,f(n) = 183で、「f(n)が素数である」はFalse
n = 7,f(n) = 303で、「f(n)が素数である」はFalse
n = 8,f(n) = 465で、「f(n)が素数である」はFalse
n = 9,f(n) = 675で、「f(n)が素数である」はFalse
n = 10,f(n) = 939で、「f(n)が素数である」はFalse
n = 11,f(n) = 1263で、「f(n)が素数である」はFalse
n = 12,f(n) = 1653で、「f(n)が素数である」はFalse
n = 13,f(n) = 2115で、「f(n)が素数である」はFalse
n = 14,f(n) = 2655で、「f(n)が素数である」はFalse
n = 15,f(n) = 3279で、「f(n)が素数である」はFalse
n = 16,f(n) = 3993で、「f(n)が素数である」はFalse
n = 17,f(n) = 4803で、「f(n)が素数である」はFalse
n = 18,f(n) = 5715で、「f(n)が素数である」はFalse
n = 19,f(n) = 6735で、「f(n)が素数である」はFalse
n = 20,f(n) = 7869で、「f(n)が素数である」はFalse


どうやら n \geqq 3ではf(n)は素数にならないっぽいので、n=3m,3m+1,3m+2(m は 整数で1以上)と置いてそれを証明してみます。

とりあえず代入してみます。

f(3m) = 3(9m^3 - 7m + 3)
f(3m+1) = 3(9m^3 + 9m + 1)
f(3m+2) = 3(18m^3 + 5m + 1)

いい感じに3 \times(多項式)になってますね。

あとはf(3m)、f(3m+1)、f(3m+1)を3で割った 9m^3 - 7m + 39m^3 + 9m + 118m^3 + 5m + 1が2以上の整数になっていれば、f(3m)、f(3m+1)、f(3m+1)が合成数になるので素数にならないことを証明できます。

それをmatplotlibのpyplotで図示して目視で確認しましょう。

f:id:a86223990:20180310161320p:plain

それぞれ2以上になってますね。

以上より答えはn = -3、1、2で解けました。


問題3

f:id:a86223990:20180310142256p:plain


f:id:a86223990:20180310180621p:plain


変数\theta (0 < \theta < \alpha)を導入して、条件から上図のように角を表します。

外接円の半径が1であることと正弦定理より
 \frac{AB}{sin(\pi  - ( \alpha + \theta)) } = \frac{BC}{sin(\theta)}
 = \frac{CD}{sin(\alpha - \theta)} = \frac{DA}{sin(\theta)} =2

よって
AB = 2sin(\pi  - ( \alpha + \theta))
BC = 2sin(\theta)
CD = 2sin(\alpha - \theta)
DA = 2sin(\theta)
と表せます。

これらを使ってkは

k = 16sin(\theta)^2sin(\pi  - ( \alpha + \theta)sin(\alpha - \theta)

と表せます。(ここまでプログラミング登場なし)

入試問題的には最大値を\alphaで表せばいいのですが、プログラミングを駆使して解きたいので0 < \alpha \leqq \frac{\pi}{2} を満たす任意の実数の入力に対して、線形探索で最大値を出すプログラムを書きました。

そのプログラムのアルゴリズムは
1:\alphaを受け取る
2:0 < \theta < \alpha の範囲で任意個に均等に分けた\thetaを用意する。
3:さっき分けた\thetaを小さい方から順に\alphaと共にkに代入して計算し、kの最大値を線形探索で求める


線形探索なので計算量はO(n)(n は \theta を分割した数)です。

問題4

f:id:a86223990:20180310142303p:plain

解法1

 z_n = 1 となる確率をP( z_n = 1)とおく。

P( z_n = 1 ) = \frac{z_n = 1となるz_nの数}{全ての z_n} です。

[全ての z_n ]は2^nで、[ z_n= 1となるz_nの数] ]は再帰を使った全探索で求められます。

計算量がO(2^n)になってしまいますが、計算時間の制限がなければ任意の入力nに対して一応この解法で解けます。


解法2

解法1は計算量が大きすぎるので速い方法で解いてみます。

a = 1、b = \frac{-1+\sqrt{3} i}{2}、c = \frac{-1-\sqrt{3} i}{2}と置きます。

z_n がa、b、cとなる確率をa_nb_nc_nと置きます。

それらを用いた以下の漸化式が成り立ちます。

a_n + c_n = 2a_{n+1}
a_n + c_n = 2b_{n+1}
b_n = c_{n+1}

A = \left(
    \begin{array}{ccc}
      1 & 0 & 1 \\
      1 & 0 & 1 \\
      0 & 1 & 0
    \end{array}
  \right)
、B = \left(
    \begin{array}{ccc}
      2 & 0 & 0 \\
      0 & 2 & 0 \\
      0 & 0 & 1
    \end{array}
  \right)x_{n} = (a_n,b_n,c_n)とすると上の漸化式は

A x_n = B x_{n+1}

と表せます。

式変形すると

x_{n} = B^{-1}Ax_{n-1}

と表せます。C = B^{-1}Aと置くと

x_{n} = C x_{n-1}

となるので

x_{n} = C^{n-1} x_1

と表せます。

C^{n-1}をプログラミングの計算力を使ってCをn-1回掛けて求めてもいいですが、計算量がO((3^2)^n)になってしまうので対角化しましょう。

D = P^{-1} C PとなるようにCを対角化します。この時、Cの固有値をdiagnolize()で求めて、\lambda_1、\lambda_2、\lambda_3とすると、

C^{n-1} = P D^{n-1} P^{-1} = P \left(
    \begin{array}{ccc}
      \lambda_1^{n-1} & 0 & 0 \\
      0 & \lambda_2^{n-1} & 0\\
      0 & 0 & \lambda_3^{n-1}
    \end{array}
  \right) P^{-1}

と表せて計算量がO(n)ですみます。

このC^{n-1}x_1 = (\frac{1}{2},\frac{1}{2},0)を使ってx_n = (a_n,b_n,c_n)を求められます。

このa_nが求める確率P( z_n = 1)です。


問題5

f:id:a86223990:20180310142307p:plain

(1)

u(t)、v(t)を普通に求めると、

(u(t), v(t))

 = (t + \frac{1}{\sqrt{t^2 + 1}},-\frac{t}{\sqrt{t^2 + 1}} + log(t))

これらをdiff()を使ってtで微分すると答えを出せます。

答えは

(\frac{du}{dt}, \frac{dv}{dt})
 = (1 - \frac{t}{(t^2+1)\sqrt{t^2 + 1}},\frac{1}{t} - \frac{1}{(t^2+1)\sqrt{t^2 + 1}})

です。

(2)

 L_1(r) = \int_1^r \sqrt{1+\frac{1}{t^2}} dtL_2(r) = \int_1^r \sqrt{ ( \frac{du}{dt})^2+( \frac{dv}{dt} )^2 } dtと表せます。

integrate()で積分してL_1(r)L_2(r)を求めてlimit()で\lim_{ r \to \infty} L_1(r) - L_2(r)を求めようと試みましたが、、、

L_1(r)はすぐ求められました、L_2(r)の式がゴツすぎるせいか中々結果を吐き出してくれませんでした。

なので式を簡単化します。

(1)で求めた導関数をよく見ると、\frac{du}{dt} = t \times \frac{dv}{dt}の関係になってます。

これを使うとL_2(r) = \int_1^r \frac{du}{dt} \sqrt{ 1+( \frac{1}{t^2} ) } dtと表せ、さらにこれを使ってL_1(r) - L_2(r)を簡単化して

L_1(r) - L_2(r) = \int_1^r \frac{1}{1+t^2} dt

と表せます。(Sympyのcancel()やsimplify()を使って\frac{du}{dt} = t \times \frac{dv}{dt}からここまで簡単化できると思ったんですが中々できなくて手で計算しました。)

このように式変形してlim()でやっと解けるようになります。


問題6

f:id:a86223990:20180310142313p:plain

(1)

まずD= (0,0,0)、A=(a_1,a_2,a_3)、B=(b_1,b_2,b_3)、C= (c_1,c_2,c_3)と置きます。

その座標を使って計算したPQ•ABをLと置きます。PQとABが垂直になることを示せばいいのでL=0を示せばいいですね。

条件AC = BD、AD = BCをsolve()で解いてa_1、a_2をa_3、b_1、b_2、b_3、c_1、c_2、c_3で表して、それらをLにsubs()してsymplify()とexpand()してもLが0にならなかったので方針を変更しました。

条件AC = BD、AD = BCを二乗したAC^2 = BD^2、AD^2 = BC^2を辺々足してexpand()で展開すると、

2a_1 ^2 - 2a_1 b_1 -2a_1 c_1 + 2a_2 ^2 - 2a_2 b_2

- 2a_2 c_2 + 2a_3 ^2 -2a_3 b_3 - 2a_3 c_3 = 0

になります。左辺をMと置きます。

Lをexpand()で展開すると、

L

 = -0.5a_1 ^2 + 0.5a_1 b_1 +0.5a_1 c_1 - 0.5a_2 ^2

+ 0.5a_2 b_2 + 0.5a_2 c_2 - 0.5a_3 ^2 +0.5a_3 b_3 + 0.5a_3 c_3

となります。

二つの式を目視で比べると、L = - 0.25 Mとなっていることがわかるので、L = 0となり、証明できました。(結局目視)


(2)

分からん。

PQを通る平面の方程式を出して、どの線分に交わるかで場合分けして、分けられた図形の体積を導出して比べたら解けそうだけどめんどくさいのでやってません。

いい感じにプログラミングで解ける方法思いついたらコメントで教えてください。

感想

最初はなんでも計算機の計算能力でゴリ押しすれば京大数学なんて解けるだろ!と思ってたんですが全然そんなことありませんでした。解けるように上手く式変形するのは人間の手でやるしかなさそうです。


どんな数学の問題を特にしても、計算機が得意なところと人間が得意なところを分担できる程度の計算機の理解が必要 だとも思いました。あと計算機が解ける形にするために数学はやっぱ大事だなって改めて思いました。数学勉強頑張ります。

参考書


行列式、固有値、固有ベクトルなど線形代数の基本的な内容を図で直感的に理解できる良本です。
 


京大が誇るハイスペック人材たち!


本当にいるハイスペック京大生 - 我、京大生ぞ