Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ProjectEuler.netを少しだけ遊んでみた / debut ProjectEuler
Search
tobi00604
November 28, 2023
0
6
ProjectEuler.netを少しだけ遊んでみた / debut ProjectEuler
tobi00604
November 28, 2023
Tweet
Share
More Decks by tobi00604
See All by tobi00604
「PG0」触ってみた / debut PG0
tobi00604
0
10
MicrosoftのAI製品がCopilotに改名した件 / microsoft copilot brand
tobi00604
0
5
砂糖には防腐効果がある / preservative effect of sugar
tobi00604
0
19
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
334
57k
How to Ace a Technical Interview
jacobian
275
23k
A Tale of Four Properties
chriscoyier
156
23k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Designing Experiences People Love
moore
138
23k
Thoughts on Productivity
jonyablonski
67
4.3k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
23k
Fireside Chat
paigeccino
32
3k
Adopting Sorbet at Scale
ufuk
73
9k
Designing the Hi-DPI Web
ddemaree
280
34k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
328
21k
Transcript
ProjectEuler.net を少しだけ遊んでみた これ、面白いです 2023/11/28
ProjectEuler.net とは • プロジェクト オイラー ドットネット と読む • https://projecteuler.net/archives •
算数や数学のクイズ問題集サイト • ただし手計算で解くのはほぼ不可能な問題ばかり • そこで問題を解くためのプログラムを作ることになる • 問題の答えさえ求まれば良いので、使う言語やツールは自由
ProjectEuler.net とは • 週に1問のペースで新しい問題が追加されている • 2023/11/28 現在、問題数は865問 • 2023/12/03 に第866問が追加される予定のようだ
• すべて無料 • すべて英語 • とはいえググれば日本語解説サイトとかも見つかる
会員登録してみる • ページ上部のメニューから Registerをクリック • 必要事項を入力 • 超簡単 • メールアドレス不要
• 本人確認も不要
問題一覧を見てみる • ページ上部にメニューがある • Recent ⇒最近追加されたばかりの問題10問 • どれも難しめ • Archives
⇒Recent以外の問題すべて • まずはArchivesの第1問からチャレンジしてみるのがよさそう
3問だけ解いてみる • 下記の3問だけやってみました • Problem 11 Largest Product in a
Grid • Problem 28 Number Spiral Diagonals • Problem 39 Integer Right Triangles • 今日(当スライド作成日)が 2023/11/28 なので 日付にちなんで、11と、28と、あと 11+28=39 にしてみました…
Problem 11 問題概要 • 右図のような 20マス x 20マス =400個の数が 与えられる
Problem 11 問題概要 • この中から、並んでいる4マスを選んで 積を計算(掛け算)することを考える • 並ぶ方向はタテorヨコorナナメ • 例えば右図の赤い字の4つの場合、
26 * 63 * 78 * 14 = 1788696 • 問題:作れる積のうち最大のものを求めよ
Problem 11 発想 • 400個の数字を二次元配列で持つ • 「上からi行目、左からj列目」の数を f[i][j] に格納 •
f[i][j], その隣, その隣, その隣 の積は以下のように計算可能 • 下方向 ⇒ f[i+0][j+0] * f[i+1][j+0] * f[i+2][j+0] * f[i+3][j+0] • 右方向 ⇒ f[i+0][j+0] * f[i+0][j+1] * f[i+0][j+2] * f[i+0][j+3] • 右下方向 ⇒ f[i+0][j+0] * f[i+1][j+1] * f[i+2][j+2] * f[i+3][j+3] • 右上方向 ⇒ f[i+0][j+0] * f[i-1][j+1] * f[i-2][j+2] * f[i-3][j+3]
Problem 11 発想 • 答えを全探索する • 4方向(下・右・右下・右上)だけ見れば良い • 例えば左方向は、別のマスから見た右方向と結果がダブるので無駄 •
f[i][j]から4方向見る処理を、全てのiとjについて試せば良い for(int i = 0; i < 20; i++) { for(int j = 0; j < 20; j++) { 下方向と右方向と右下方向と右上方向をチェック; } }
Problem 11 考察 • 二次元配列は f[20][20] ではなく f[26][23] でやる •
4マス見るときの配列外参照を防ぐ • そもそも二次元配列をどう作るか • 400個の “文字列” が半角スペースで区切られて与えられる • ⇒String.split() で区切る • ⇒Integer.parseInt() で数値に変換する • あとは int[][] 型の二次元配列に詰めていく
None
Problem 11 提出 • このプログラムを動かして出力された答えを提出 • ソースコード自体を提出するわけではない • 正解でした
Problem 28 問題概要 • 中央の1から順に時計回りの渦巻き状に数字を並べていき 正方形を作ることを考える
Problem 28 問題概要 • このとき対角線上に位置する数字 (右図の赤い数字)の合計は 1+3+5+7+9+13+17+21+25=101 • 問題:これを5x5の正方形ではなく 1001x1001の正方形でやったら
合計はいくつになるか?
Problem 28 発想 • 1+3+5+7+9+13+17+21+25+31+37+43+49+ … • 1, 3, 5,
7, 9 の部分は2ずつ増加している • 9, 13, 17, 21, 25 の部分は4ずつ増加している • 25, 31, 37, 43, 49 の部分は6ずつ増加している • つまり「4個進むたびに、増加量が +2」されている • なぜ4個進むたび? ⇒正方形は辺が4本あるから! • なぜ増加量 +2 ? ⇒渦巻き1周ごとに辺の長さは 2 増加するから!
Problem 28 考察 • ゴールマスの数字は? • 5x5の正方形では 25(=5^2) だった •
1001x1001の正方形では 1002001(=1001^2) になる • 「4個進むたびに、増加量が +2」のルールに従って、 1002001に到達するまで加算していけば良い • 加算していく値は2000個程度なのでそんなに重い処理でもない
None
Problem 28 提出 • 正解でした
Problem 39 問題概要 • 周の長さが p であるような直角三角形を作る、 ただし3辺の長さはいずれも整数とする • つまり小数とかはダメ
• 例えば p=12 のとき、作れる直角三角形は 3辺の長さが {3, 4, 5} の1種類だけ 3 4 5
Problem 39 問題概要 • 例えば p=120 のとき、 {20, 48, 52},
{24, 45, 51}, {30, 40, 50} の 3種類を作れる • 問題:最もたくさんの種類の 直角三角形を作れるのは、 p がいくつのとき? (ただし p は1000以下とする) 40 20 48 52 24 45 51 30 50
Problem 39 発想 • 直角三角形を作れる3辺セットをピタゴラス数という • 例えば {3, 4, 5},
{30, 40, 50} • ピタゴラス数のうち、3つが互いに素であるものを 原始ピタゴラス数という • 例えば {3, 4, 5} • 「互いに素」とは何か、についてはここでは説明しません…
Problem 39 発想 • また、ユークリッド式というテクニックがある • 2つの自然数 m, n が
「m>n」かつ「互いに素」かつ「偶奇が異なる」だと、 {m*m-n*n, 2*m*n, m*m+n*n} は原始ピタゴラス数になるというもの • (m*m-n*n)+2*m*n+(m*m+n*n) = 2*m*(m+n) が周の長さとなる • 結局今回の問題では、上記の m, n のペアを全探索して、 周の長さ 2*m*(m+n) を漏れなく生成すればよさそう
Problem 39 考察 • 今回の問題は、周の長さ p は1000以下という制約付き • 2*m*(m+n) が1000以下ということは、mが23以上だとオーバー
• mは1から22まで調べれば網羅できそう • 2*m*(m+n) をひとつ生成したら、その相似も忘れずに! • 2*m*(m+n) の直角三角形が作れるならば、 それの整数倍、つまり 4*m*(m+n), 6*m*(m+n), … の直角三角形も作れるはず
None
Problem 39 提出 • 正解でした
感想 • 正解するともちろん嬉しいが、解く過程も面白い! • Problem 28 の「4個進むたびに、増加量が +2」のような ロジックを組み立てる手がかりを発見できるとテンションUP •
新たな知識が得られ、思考力と実装力が鍛えられる! • Problem 39 で使った「ピタゴラス数」や「ユークリッド式」は 今までまったく知らなかったが、おかげで理解が深まった • 問題ごとに方針を立てて、コードという形にする訓練になる
感想 • サイトのUIがシンプルで使いやすい! • アカウント登録も簡単だし、各ページも見やすい • 「プログラミングで数学を解く」が気軽にできる! • そういうのが好きな人はハマるはず •
作りたいものがないプログラマーにはうってつけのサービス • ただ、数学や英語が苦痛な人にはオススメできないかも
ほかにも機能は豊富 • まだ私がよく知らないProjectEulerの機能(一例) • フレンド機能 • フレンド登録したユーザの進捗が分かるのだろうか? • スレッド機能 •
正解済みの問題は、掲示板で他ユーザの意見を閲覧できるっぽい? • 統計機能 • いろいろユーザに関する情報が見れるっぽい?
終わりに • 問題の解き方は人それぞれ • 当スライドで紹介した解法・コードは あくまで一例で、最高効率ではない • 読者の皆様もぜひ! 以上 レオンハルト・オイラー
(1707-1783)