じばるどーね!

趣味、思想、妄想、学問、ごった煮ブログ

【クイズ】どっちが大きい?極限二択クイズ!!

 こんにちはーーー!!

 じばるどーねのとぼです。「大は小を兼ねる」なんてことわざがあるように、物事は大きければ大きいほど良いものですよね!!(これは罠で、軽量化やミクロ化や圧縮などの技術も滅茶苦茶大事です)。

 まあ、そんな訳でですね、今回は「どっちが大きいか?」をクイズ形式で出題したいと思います!!

 なんと今回のクイズは2択です!! いろんな数や単位、さらにはモノなどが出てきますが、もし知らなくても適当にどっちか選んじゃってください!!

 

 

どっちが大きい?極限二択クイズ!!

  では、これから次々に2つの数字や単位を見せていきますので、「大きい」と思う方を選択していってください!!全部で12問あります!!

 

第一問 大きいのはどっち?  難易度 : ★

選択肢

 

解答

 

 

第二問 大きいのはどっち?  難易度 : ★

選択肢

 

f:id:tb9810w124816:20180326184528p:plain

解答

 

 

第三問 大きいのはどっち?  難易度 : ★★

選択肢

 

解答

 

 

第四問 大きいのはどっち?  難易度 : ★★

選択肢

 

解答

 

 

第五問 日本円になおしたときに大きいのはどっち?  難易度 : ★★★★★★★★

選択肢

 

f:id:tb9810w124816:20180326184634p:plain

 

解答

 

 

第六問 大きいのはどっち?  難易度 : ★★★

選択肢

 

解答

 

 

第七問 大きいのはどっち?  難易度 : ★★★★

選択肢

 

解答

 

数の名前 の記事を参考にしてもらえれば、大きな数の日本名称が一目でわかります。

 

第八問 大きいのはどっち?  難易度 : ★★★★

選択肢

 

解答

 

 

第九問 体積が大きいのはどっち?  難易度 : ★★★★

選択肢

 

解答

 

 

第十問 体積が大きいのはどっち?  難易度 : ★★★★

選択肢

 

解答

 
 

ukiuki-express.com  ランキング形式で各惑星の大きさなどが書かれていてわかりやすいです。

 

d.hatena.ne.jp太陽系の構成が視覚的に分かります。

 

 

第十一問 大きいのはどっち?  難易度 : ★★★★★

選択肢

 

解答

 
 

ロボットの大きさ比較動画。途中から宇宙動画になる。

 

第十二問 大きいのはどっち?  難易度 : ★★★★★★

選択肢

 

解答

 

http://lumens.blog.fc2.com/blog-entry-23.html


 

まとめ

あなたは,

 

問中,

 

問正解しました!!

   いろいろな大きいものに関するクイズをしました。なんかこのタイプのクイズならまだまだネタはありますし、作ってて楽しかったので、多分また第二弾やります。次回は上級編とかですかね?

 でも、今度は「小さいのはどっち?」なんてのもいいかもしれませんね。

 

関連記事

 いままでに作ったクイズ記事!

 

yadrfu.hatenablog.com

yadrfu.hatenablog.com

 

【プロジェクトオイラー】数学の難問をプログラムの力で解く!!Part1(オイラープロジェクトの紹介)

 こんにちは。じばるどーねのとぼです。

 皆さん、数学は好きですか?

 プログラミングとかやったりしますか?

  わたし、数学とかプログラムで難しい問題を解く行為が(双方全くつよくないしむしろよわいのだけれど。精進しろ)好きで、競技プログラミングとかもちょこちょこやってるんですよ。

 とはいっても今やっているのは日本でとても有名なAtCoderだけなんですが。世界的に有名なCodeforcesCodeJamなどにも今後挑戦してみたいなと思ってはいます。英語と夜に弱いので、日本時刻で真夜中に行われる英語のコンテストであるCodeforcesなどはきついですが...。

 ここでいう「競技プログラミング」ってのは、プログラミングの問題を制限時間の中でいかに早く、多く解けるかを競う、比較的短時間のコンテストです。AtCoderなどの競技プログラミングでは、各問題にはいくつかのデータセットがあって、各データセットでは入力データが与えられるのでそれに対応した正しい出力データを出したときのみ正解(AC)となります(部分点がある問題もあります)。また、各問題に対して正しい出力を出す場合でも、各問題に与えられた実行時間の制限時間(1秒とか3秒とか)を超えてしまうとTLE(時間制限エラー)となってしまいます。

 一方で、1つの問題に対して1つの解答があり、かつ各問題に実行時間制限がないようなプログラミングの問題を提供するサイトも存在します。その中の1つに、「Project Euler(プロジェクト オイラー) というものがあります。かの偉大な数学者オイラーの名を冠している通り、整数問題や幾何問題などの数学の難問をプログラムの力を使って解こう!というものです。

 

Project Eulerに挑戦してみよう!!

 TLで微妙にこのプロジェクトオイラーが流行っていて、数学とプログラミングが好きな私にはうってつけの内容だったので早速やってみることにしました!!

 では早速、Google先生に[Project Euler]で検索をかけてみましょう。

    ...。

f:id:tb9810w124816:20180325171613p:plain

 

_人人人人人人人_
> 全 文 英 語 <
 ̄Y^Y^Y^Y^Y^Y^Y^ ̄

 

...はい。このように、少しスタートの威圧感が強いですが、まずは登録をしましょう!

f:id:tb9810w124816:20180325172527p:plain

右上の「Register」とかかれたボタンを押して、Username(ニックネーム)やPasswordを決めて登録をしましょう!

 登録が終わったら「Archives」(アーカイブ)と書かれたボタンをクリックすれば早速問題一覧を見ることができます!!

f:id:tb9810w124816:20180325173050p:plain

...こんな感じで問題一覧が表示されています。現在なんと問題数は600を超えています!気長に楽しみましょう。 

 ちなみに各問題の「Difficulty」ってとこにあるオレンジ色のメーターが、その名の通り各問題の難易度の指標になっています。この難易度メーターは5%~100%まであり、メーターが低いほど簡単なものになっています(私は現状40%以上の問題を解けていません...)。見ての通り最初の方の問題は簡単なものが多いので、最初は順番に解いていきましょう。

 まあ実際に、最初の問題を見てみましょう。

f:id:tb9810w124816:20180325173707p:plain

 和訳すると、「1000未満の数で3または5の倍数である数をすべて足すといくつになるか求めなさい」ってことですね。

 (英語でbelow~やunder~は全て~未満となることに注意してください。以下であれば、"5 or under(5以下)"のように"OO or under/below"のような形で表されます。)

 数学の問題として取り組んだらちょっと計算がめんどくさいですが...、プログラムの問題としてはよくある「Fizz Buzz問題」と同程度で、簡単に解けるものですね。

 問題が解けたら、下の回答フォームからAnswerを入力しましょう。

(Confirmation Codeを入力するのを忘れずに!たまに1と7とか見分け付きづらいときがありますが、そういう時は画像をクリックすると新しい画像に更新されます!)

 

f:id:tb9810w124816:20180325174148p:plain

入力した答えが正解であれば、

 

f:id:tb9810w124816:20180325182348p:plain

 不正解であれば、

 

f:id:tb9810w124816:20180325181717p:plain

  といったように、全身白タイツの男が回答の正誤に一喜一憂してくれます。かわいらしいですね。

 

   「英語アレルギーで、問題が解けない!!」

という方も、もしかするといらっしゃるかもしれません。でも大丈夫です。プロジェクトオイラーには有志の方々によって作られた日本語版問題Wikiがあるのです!

 それがこちら↓↓

f:id:tb9810w124816:20180325183436p:plain

 ただし、後半の問題にはまだ翻訳されていないものもあるので、英語ガチ勢の方は是非翻訳完成目指してください(投げ)。

 なお、私は、「むしろ原文で問題解いた方が英語の勉強にもなる!!」と思いながら、2問に1問くらいのペースで和訳をガン見しています(。

 だって細かい条件が英語だと理解しにくいんだもん...(甘え)。

 

 ちなみに、問題に正解すると自分が何番目に正解したかわかるだけでなく、その問題に関する議論を他の正解者とすることができるようになります(議論スレッドに入れるようになる)。このスレッドでは、最初の100個のコメントと最新の100個のコメントが表示されます。自分のソースコードと他の人のソースコードを比較したり評価しあったりするのも成長につながると思います。(なお、議論は英語で())

 

 

ちなみに、私のProblem1に用いたソースコード(C++)のメイン関数はこんな感じです↓↓

 

 

int main() {
  int sum = 0;
  for (int i = 1; i < 1000; i++)
        if (i % 3 == 0 || i % 5 == 0)  sum += i;
   cout << sum << endl;
   return 0;
}

 うん。おいしい。

 

 まあ、何の変哲もない感じですね。Problem1なので、オイラープロジェクトの数ある問題の中でも一番簡単なものになっています。

 

 もう少し難易度の高い問題(Difficultyはやはり5%だが)を見てみましょう。

f:id:tb9810w124816:20180325190009p:plain

 Problem14。これは、有名な数学の未解決問題の1つ「コラッツ予想」に関する実験をする問題です。数学好きとしては題材がコラッツ予想ってだけでワクワクしますね。

   コラッツ予想は、任意の正の整数は

  ・偶数なら2で割る

  ・奇数なら3倍して1を足す

  という操作を繰り返すと最終的に1になる、というものです。

「ほんとかなぁ」(ゴロリ風に)

と思うわけですが、今までのところ反例となる整数は見つかっていないため正しいのではないかと考えられている命題です。

 で、今回は正の整数を100万未満に限定したとき、1に至るもまでの操作の回数(ステップ)が一番長くなるのはどの整数だろうか、という問題になります。

 いやー、楽しいですね。

 興味のある方は是非自分で実装して解いてみてください。

 数行先でネタバレします(ソースコード載せます)

 

 

 

 

 

 

 

 

 こんな感じで実装しました。

//EP14.コラッツ問題

int main() {
  int num[1000001] = { 0 };
  num[1] = 0, num[2] = 1;
  int id = 1;
  for (int i = 3; i < 1000000; ++i) {
   if (i % 2 == 0) num[i] = 1 + num[i / 2];
   else {
   ll t = i;
   int s = 0;
   while (t >= i) {
    if (t % 2) t = 3 * t + 1;
    else t /= 2;
    s++;
   }
   num[i] = s + num[t];
   }
   if (ans < num[i]) {
    ans = num[i];
    id = i;
   }
  }
  cout << id << endl;
  return 0;
}

  さっきよりは長いコードになりました(それはそう)。

  配列numがその名の通り各整数を表しています。さすがに1~100万の整数すべてに対してはじめから操作をシミュレーションしていったら時間がかかりすぎてしまうので、偶奇に場合分けして漸化式に落とし込んでいます。

   num[1]=0

 iを2以上の整数として

 num[i]= 1 + num[i/2] (iが偶数の時)

                 s + num[t]    (iが奇数の時)

(ここでsはtがi未満の値になるまで2で割ったり3倍+1したりする操作を繰り返した回数、tはその結果最後の操作で遷移したi未満の整数)

と漸化式を立てました。奇数状態が続いたら必ずしも高速に動くとは保証できない気もしますが...

 

 まあ、細かいことは気にしない

f:id:tb9810w124816:20180218162853p:plain

 おしまい。

Part2へ続く!!

 

yadrfu.hatenablog.com

 

遅まきながらGoogle home miniを使ってみた!

OK, Google! 僕の頭から記事を書いて!

 ...であれば、楽でいいのになあ。まあ、自分の頭の中を整理して、アウトプットする行為が楽しいから、ブログやっているんですけどね。こればかり、Google homeに任せることはできませんね。

最近の一人暮らし

最近の料理は...

 こんにちは!くりすぷです。

 福岡から東京に来て早2,3年ぐらい経ちました。最初は料理を作りすぎるなど、いろいろやらかしましたが、すっかり慣れまして、今では料理しなくなりました。全く成長してないですね。

 というのも、自宅でおいしいものを食べるというのは時間がかかって大変なので、「おいしいものは外食など外部委託して家ではカップ麺やパスタなど最低限栄養がとれるものでいっか(^○^)」という結論に至りました。このような、メリハリをつけた食生活によって、外食の食事では味に対して敏感になれます。おなかが極限にすいているから、そのあとのごはんがうまい、みたいなものです。内食が大しておいしくないから、外食がうまい。その様子は過去記事↓にかいてあるので、こちらもどうぞ。

 

yadrfu.hatenablog.com

Google home miniを導入した一人暮らし

 Google home miniの何がいいかというと、その小ささとセットアップの簡単さと機能の非局在化です。

 小さいため、どこにでも置けるという安定感があります。スマホ1個でセットアップできるというのも、簡単でいいです。

 声で動くので、一人暮らし用の家のどこにいても、だいたい反応してくれて、今日の天気を教えてくれたり、近くのマクドナルドを教えてくれたり、タイマーをセットしたりしてくれます。

 「OK, Google. 3分計って」と言って、カップ麺が作れる。

 「OK, Google. 8時にアラームをセットして」と言って、朝を迎える。

 「OK, Google. NHKラジオを流して」というと、ラジオが聞ける。

 結構いろんなことができて楽しいです。食の面でいえば、私のカップ麺ライフを支える相棒になりそうです。スマホでゲームをしているのをいちいち中断してカップ麺を作るというのはどこか間抜けな感じがしますし。カップ麺のために一時中断したくないです。かといって、キッチンタイマーがある場所に行きたくない。そういうとき便利です。

 僕は物理で本を読むときに簡単な単語を調べるときにも使っています。Kindle版とかの電子書籍だと、すぐに単語の意味が調べられて便利ですが、ああいう感じです。読書生活にも役に立っています。

 今のところ、使い始めて2,3日なので、いろんな使い方を見つけていきたいと思います。こんな感じで、日々なにかテーマを決めていろいろ実験してます。どんな使い方をしようか、とか、どの程度反応できるかとか。皆さんも遊んでみてはどうでしょうか。

【プロジェクトオイラー】数学の難問をプログラムの力で解く!!Part2(序盤で使える道具・知識)

 こんにちは。じばるどーねのとぼです。今回もProject Euler(プロジェクトオイラー)」について書いていきたいと思います。...そういえば、「プロジェクトオイラー」のこと間違えて「オイラープロジェクト」って言っちゃうの私だけ???

 

 さて、Project Eulerがどういうサイトであるかは前回紹介しました。

 

f:id:tb9810w124816:20180325171613p:plain

 

 

f:id:tb9810w124816:20180325173050p:plain

 

 とりあえず、プログラムで解く数学の問題がたくさんあると。(ざっくり)

 ですが、やっぱ解くだけじゃ直に飽きてしまうかもしれません。

 Project eulerでは問題を解くモチベーションにつながる、Level やAward というシステムがあります!!

 Levelは0からスタートして、問題を25題解くごとに1上昇します。Levelが1以上になると、自分のLevelのコミュニティに所属できます。さらに、現在ですと、Level2以上になるとサイトに名前が載ります。ついでに、今の私のLevelは2です。解いた問題数は51問でかなりひよっこLevel2ですが。まあ、だんだんと解ける問題が少なくなってきて辛いわけですが、頑張ってLevel3にはなりたいですね。

 

f:id:tb9810w124816:20180325200209p:plain

  Level10以上位から超強い領域だと感じています...。

 

 さて、そんなProject Eulerですが、今回は序盤(Level1になるのに必要な)で使える基本的なプログラミングや数学の知識について、実際の問題を見ながら説明していきたいと思います。

 

 

1.ユークリッドの互除法

 名前だけなら聞いたことがあるという方も多いのではないでしょうか。ユークリッドの互除法は「2つの自然数(整数)の最大公約数を求める」のに使うアルゴリズムです。

 例えば、「7920と2475の最大公約数を求めよ」のような問題は、ユークリッドの互除法によって簡単にすることができます。

   ユークリッドの互除法アルゴリズムの基本的な流れを以下に示します。

 1.自然数xとyの最大公約数gcd(x,y)を求める(x≧yとする)

 2.もしxがyで割り切れるならばgcd(x,y)=yである (終了)

 3. xがyで割り切れないならばgcd(x,y)はxをyで割ったときの余りとyの最大公約数

  に等しい。xをyで割った余りをx%yと書き表すと、gcd(x,y)=gcd(y,x%y)となる。

 4. x=y,y=x%yに置き換えて2.に戻る

以上になります。ここで、yで割ったときの余りは0以上y-1以下の自然数であるので、必ずy>x%yとなることから、4.でx=y,y=x%yに置き換えてもx≧yとなります。しかも、毎回の繰り返しで必ずx,yが小さくなるので、有限ステップでアルゴリズムが終了することも分かります。

 では、先ほどの例題「7920と2475の最大公約数を求めよ」をユークリッドの互除法を使って解いてみましょう。

  求める最大公約数をgcd(7920,2475)とします。

  7920÷2475= 3 余り 495だからgcd(7920,2475)=gcd(2475,495)

     2475÷495= 5 余り0で割り切れるからgcd(2475,495)=495

    よってgcd(7920,2475)=495です。(終了)

...どうでしょうか。一個一個割れるか試すのではなかなか思いつかない495という答えも比較的簡単に出せてしまいます。

  更に、ユークリッドの互除法には以下の2つの応用が利きます。

1.自然数x,yの最小公倍数lcm(x,y)も一緒に求められる。

   最小公倍数lcm(x,y)は、要はxとyに共通している約数にx,y固有の約数を掛け合わせたものになりますから(この方法より小さくできる公倍数はない)、

lcm(x,y) = gcd(x,y)×(x÷gcd(x,y))×(y÷gcd(x,y)) = x×y÷gcd(x,y)

ということになります。gcdが求まった時点でlcmも計算1つで求まってしまうわけですね!例えば7920と2475の最小公倍数なら、7920×2475÷495=7920×5=39600より答えは39600となるわけです。

2.複数の自然数の最大公約数にも応用できる

自然数がx,y,zと増えて、この3つの最大公約数gcd(x,y,z)を求める場合でも、結局gcd(x,y,z)はgcd(x,y)とzの最大公約数であるとみなせるので、

gcd(x,y,z)=gcd(gcd(x,y),z)となりわざわざ3つの公約数を見つける必要がなくなります。自然数が4つ、5つ、6つと増えても同様です。例えば7920と2475と231の最大公約数は、「7920と2475の最大公約数」である495と231の最大公約数と等しいため、

495÷231=2余り33,231÷33=7余り0ということで、答えが33であると分かるのです。

<実装>

//ユークリッドの互除法の概略コード

gcd(x,y){

   if x<y : swap(x,y)   //x≧yとなるように交換する
   if x%y==0 : return y   //xがyで割り切れたら答えはy

   else : return  gcd(y,x%y)  //gcd(x,y)=gcd(y,x%y)である

}

 とまあこんな感じです。概略の作法あんま分かってないので勘弁してください。

<Project Eulerにおける例題>

f:id:tb9810w124816:20180329111325p:plain

「1から20までのすべての整数で割り切れる最小の数を求めよ」という問題です。

 もし自分で考えたい方はここでストップ。いますぐProject Eulerに登録して解こう!

 (数行先で説明)

 

 

 

 

 

 

 この問題、つまりは1から20の最小公倍数を求めよって話ですよね。

 なので、答えは1~20の最小公倍数をかけていけばいいです。

 したがって、はじめ答えをans=1として、lcm(x,y)=x×y÷gcd(x,y)の性質よりiを2から20まで順に増やしていってans=ans×i÷gcd(ans,i)とすれば完了です。

//EP5の解法
ll gcd(ll x, ll y) {   //ユークリッドの互除法
   if (x < y) swap(x, y);
   if (y == 0) return x;
   return gcd(y, x%y);
}

int main() {
   ll ans = 1;  //答え(llは約10^18までの整数を扱える型(これはC++。Pyの方がよい)
   for (int i = 2; i <= 20; ++i) {
     ll t = gcd(ans, i); //今の答え(lcm)とiの最小公倍数を答えに掛ける
     ans *= (i / t);
   }
   cout << ans << endl;
   return 0;
}

 

2.素数判定(エラトステネスの篩)

 素数判定問題は有名ですが、プロジェクトオイラーでも頻出。いかに早く素数列を作れるかが重要だと思います。が私はとてもよわいので今のところおっそいよわよわな生成法しかしていません。競プロだとまずいかもしれないです。Project Eulerの場合は時間制約がないので正解できます。

 速いエラトステネスの篩については以下のサイトをご参照ください。

qiita.com

まあ、ある数が素数かどうか判定したいとしますね。

「2525123は素数ですか?」という問題に対して「2で割れない、3で割れない、4で割れない、5で割れない、6で割れない、7で割れない、...」と全部試していったら時間かかりすぎる!ちなみに、2525123は素数です。

 「nが素数ですか?」という問題に対して1からnまですべてで割ってみることで判定したらオーダーO(n)。まあ、少し考えると、もし自然数xが素数でないならある自然数z,yを用いてx=z×yと書き表され、z,yの少なくとも一方は√x以下であることから1~√nまでの数で割って調べればいいとわかりこれでオーダーはO(√n)に減らせるんですが、まだ遅い。そこでエラトステネスの篩(ふるい)が登場します。

 よく考えてみてください。ある自然数nが2で割れないと分かった時点で4や6や8などの偶数で割れないことは明らかです。わざわざ試す必要がない。同様に3で割れないと分かった時点で6,9,12,15などの3の倍数で割れないことは明らか。わざわざ試す必要がないので省略します。つまるところ√n以下の素数で割れるかだけ調べればよくなります。このように「2の倍数でない、3の倍数でない、5の倍数でない、...」と徐々に素数かどうかの判定を絞っていく様が自然数という砂を篩に掛けているようなので、このアルゴリズム「エラトステネスの篩」といいます。

 vectorというのは動的な配列です。つまり、配列の要素数を宣言しなくてもいい配列です。このvector素数を格納していきます。

vectorのerstが0のときは素数でない、1のときは素数であることを意味します。ですが、このコードぶっちゃけ全然ふるえていません。精々探索を先に話した方法で√nまでにしたことと(forの条件式dx*dx<=nより)、偶数をスキップしたことくらいです。3の倍数も飛ばすべきかもしれません。ただ、5の倍数も,7の倍数も、と条件を増やしすぎると却って条件式が長くなり遅くなる場合もあります。

//エラトステネスの篩 prime(n)[k]で1~nまで探索して(k+1)番目の素数を出力
vector <int> erstlist;
void prime(int n) {
 vector<int> erst;
 for (int i = 0; i < n; ++i) erst.PB(i);
 erst[0] = erst[1] = 0;
 for (int dx = 2; dx*dx <= n; dx++) {
  if (erst[dx] == NULL) continue;
  for (int i = dx * 2; i < n; i += dx) erst[i] = NULL;
 }

 for (auto i : erst) if (i) erstlist.PB(i);

 return;
}

 ぶっちゃけエラトステネスの篩難しいです。ふえ~~~。誰か教えて。

 でも、素数ネタはProject Eulerにいっぱいあります。もうほんと、1番多いかもしれない。

 

<例題:簡単>

例えばProblem10は単純に2百万未満の素数をすべて足せ、というもの。まあ、素数表を作って投げておしまいです。

f:id:tb9810w124816:20180330170930p:plain

<例題:ちょい難>

f:id:tb9810w124816:20180330171419p:plain

まず英語がきついので、前回紹介した日本語wikiを使いましょう。

(弱い。でも少しは自分で頑張って読んでみてからwikiは見るし、そうした方がいい)

f:id:tb9810w124816:20180330171828p:plain

すると、問題の意味が分かります()

要するにnの整二次式の1次項の係数と定数項をうまく変えて、nに0から順に数字を入れていったときになるべく連続で値が素数になるようにしなさい、という問題です。当然、素数表がないと解けません!!逆に素数表さえあればあとは全探索するだけ!!...とおもって解いたら私は答えが出力されるのに100秒くらいかかるクソコードを生成しました。

 まあ、bの絶対値は素数になるなどの工夫をして多少は探索量減らしたんですが...Discussionにはもっと良いコードがありますね。

 

<おまけ>

 最強の方法:時間かかってもいいから素数表を生成し、ライブラリと同じ感覚で素数表配列を予め作っておく。これで実際の問題に対してO(1)で素数表が作れるよ()

 

3.modと冪・階乗

 冪とか階乗とかで無茶苦茶大きい数について下n桁を求めよ、とか各桁の数字を総和を求めよとかとかいう類の問題もプロジェクトオイラー序盤では結構あります。無論、単純に計算しているだけでは桁が大きすぎてオーバーフローしてしまいます。

 ここでは、2つの問題のパターン

 1.大きな数の下10桁を求めるパターン

 2.大きな数の各桁の総和を求めるパターン

について解法を説明します。なお、2.の方が1.の上位互換です。

  まず、1についてざっと説明すると、下10桁は結局10000000000で割ったあまりですので、計算がオーバーフローしないタイミングで逐次%1000000000(10000000000で割ったあまりを求める)してゆけばいいだけです。いちいち10000000000ってかくのが面倒なのではじめにBIG=10000000000とでも宣言しておきます。

  例えば2の1000乗の下10桁を求めたいとすると以下のようなC++プログラムが書けます。

int main() {
   ll BIG = 1000000000;
   ll ans = 1;     //2^0=1
   for (int i = 0; i < 1000; ++i) ans = (ans * 2) % BIG;
   cout << ans << endl;
   return 0;
}

ちなみにPythonだと2の1000はprint(2**1000)と打つだけで出力されます。オーバーフローしません。それに一瞬で出ます。Python強くない?

f:id:tb9810w124816:20180330161757p:plain

Pythonでprint(2**1000)とだけ書いて出力した結果(2の1000乗)

 実行結果、2の1000の下10桁は「668069376」でした。

 なお、問題のパターンとしては以下に説明する2.のパターンですが2の1000乗にまつわる問題はProject Eulerの16問目にあります。また97問目には巨大素数を下10桁を求める問題があり、今回紹介した方法をそのまま用いて突破できます。

 

 次に2についてですが、そもそもにおいてこういった問題はC++ではなくPythonを使えば問題ありません。Project Eulerは時間制約がないですし、Pythonなら実際2の1000乗などの大きい数もオーバーフローしないで計算できますし計算速度も1秒かからない。草。でも、それでもC++でやりたければ方法があります。プログラムに筆算を指せればいいのです。そして各桁を1つの配列要素にして繰り上がりは変数carryで管理します。例えば、C++で80!(1から80までの整数を全てかけたもの)を計算してその各桁の和を求めたいときは以下のようなコードを書けばよいことになります。

//80!の計算
int main() {
   ll sum = 0;
   int ans[1000] = { 0 }; //念のため1000桁用意
   ans[0] = 1; //はじめ最下位は1(0!)
   for (int i = 1; i <= 80; ++i) { //1~80までかけていく
      int carry = 0; //桁の繰り上がり
      for (int j = 0; j < 1000; ++j) {
        ans[j]=(ans[j]*i)+carry;   //各桁i倍して繰り上がりを足す
        carry = ans[j] / 10;
        ans[j] %= 10;
      }
   }

for (int i = 0; i < 1000; ++i) sum += ans[i];
cout << sum << endl;

return 0;
}

なお、Pythonだと80!ごとき、BIGで割らなくても計算できます。以下のような簡単で短いコードを書くだけで全桁計算できます。

ans=1
for i in range(80):
     ans*=(i+1)
else:
     print(ans)

 

で、例えば80!の各桁の総和を求めたいとすれば、以下のようなコードを追加します。

sum=0
while ans>=1:
      sum+=ans%10
      ans//=10
else:
      print("The sum is",sum)

この実行結果が以下です。

f:id:tb9810w124816:20180330174733p:plain

 ただし、1つ注意点があります。ans//=10の部分をans/=10とするとansが浮動小数点として計算され、小数点以下の切り捨てがされません。Python初心者の私としては驚きました、これ。

でも除算「/」の代わりに整数範囲での除算「//」という演算子があるので無問題ですね!!

。。。(-ω-;)ウーン。Pythonつよいなぁ。 

 なお、問題設定を100!の桁総和に変えただけの問題がProject Eulerの20問目にあります。

4.まとめ

 Project EulerやるにはPythonが有利。機械学習Python!! なんなら私程度のレベルなら競プロの問題もPythonでいい気がする(時間制約がC++でないと困難であるような定数倍問題はそもそもなかなか解けない)。でもまあ、素数表ならC++の方が早く作れる。でも、極論言えば素数表は一回手元で作ってそれを配列かなんかに初期値として入れとけばいい。あれ?、Python神じゃん!!Python勉強します。皆さんも一緒にPython勉強しましょう。

 

5.関連記事

 Project Euler記事第一弾です。あと、ここまで書いてきて今更気づいたんですが、Project Euler序盤で使える最強の武器「next_permutation」の話し書き忘れました。辞書順問題とかに使えます。これを含め、豊富なライブラリがあるからやっぱC++もいいなぁ...。次回書きます、続く。

 

Part1

yadrfu.hatenablog.com

Part3

yadrfu.hatenablog.com

 

 

反省と今年度の抱負 [己の為にブログを利用すること]

 こんにちは、「じばるどーね」のとぼです。今週分であげようとしていた記事の一部のシステム(?)が上手くできないのですが、一週間に1記事上げることはこのブログを書く際に相方と決めた約束でもあるため、かわりにクソ記事を生成します。

 「クソ記事」といいますが、「クソ」なのは私自身でした。

 ここ最近のだらしのなさ。最近達成したことといえばグルコスAppで幻想のサテライトS++取得したことぐらいです。

 ですので、今回のテーマは「クソなワタシ」について書く「クソ記事」です。

 

 

 客観的に見つめた自分と反省点

 1.だらしがない

 はい。これがすべてを表している気がします。でも、「だらしない」っていうと範囲が広いし、曖昧ですね。私が自分を「だらしない」と感じる要素は複数ありますが、(全くないわけではないが)正直あまり直す気がないものもあります。でも本当に、「なおさないとヤバイ」、「社会不適合藻屑of屑」になる、とおっもている点があって、それは、

 ・計画性が皆無であること

 ・中途半端

の2点であります。これらは1日を虚無にする原因になったりするし、自分自身を嫌悪してしまうし、信用とかいろいろ損失する原因にもなりそう()

 2.計画性の皆無

 一日で何をするのか、一週間で何をするのか、一か月で何をするのか、そういった目標がないと、人は漠然とした一日を過ごしてしまうと思います。漠然と、怠惰に過ごす一日というのは、脳の記憶として保存するに足る情報も少ないからか、以前紹介した「ジャネーの法則」によってあっという間に過ぎ去ってしまうように感じます。

 わたしは、大学入学後、この自らの欠点と向き合う為になんらかの「メモ帳」を常備するようにしました。これによって今月の定まった予定だとかノルマだとか周辺的な記憶を以前よりは留めることができるようになりました。

 でも、「メモ帳」の存在自体を忘れたり、どうにも覚えてはいてもモチベーションに繋がらなかったりしています。

 また、あまりにも時間にルーズな節があります。人に合わせる時間を作る余裕がない、というか自分のことで夢中になってしまうのです。恐ろしいことには、時間があまりあるときにダラダラと過ごしたくせに、ある予定の開始時間が迫ると思い出したようにそれとは別の自分のタスクをギリギリまでやりだすという、屑行動をしてしまうことがあるのです。

 

 3.中途半端

 とにかく、いろいろなことに興味が湧くのですがその先へつながらないことが多すぎる。我ながら「1番ダメなパターン」ですね、これは。趣味・勉強・バイト・ゲームが、特に「自主的な行動」、「独学」とかがほんっとに中途半端。わたし塾通ったことないのですが、中学の時とかは自発的に「数学」を独学し、っそれを楽しんでいました。でも、最近は心から。内的な欲求によって楽しめていることがあまりないのではないかと感じてしまいます(もちろん今でも数学は好きではあるので整数問題などたまに解いたりして遊んだいますが)。で、わたし「長期的な精進」が全然できないんですよ。テスト前の猛勉強とかは得意だし地味に好きなんですけど。三日坊主になりがちなんです。あと、ある目標に対してどのようなアクトをすればそえが実現しうるのかを頭で思い描いておきながらそのイメージとは程遠いもしくは一切の行動を起こさないケースが多すぎる。・・・・うーーん、なんだかネガティブみが強くなってきてしまったので、自分の長所も見つけてみたいと思います。

 4.逆に、自分のプラスな面(と思っていること)

 まず、なんだかんだギリギリになったりはしつつも最低限以上のタスクはこなします。また、一度熱が入りだすと物凄い集中します。まあ、これのせいで時間にルーズになったっりするし、この熱がなかなか入らないから困るんだけど。また、これもいい意味でも悪い意味でも取れるんですが、裏表が少ないです。つまるところ一般的に包み隠すべき感情や意見もつい顔や口に出ちゃうこともあるんですが。あと、自分に不満が多いため人」のリスペクトすべき点が滔々と湧いてきます。湧くだけじゃ使えませんけどね。

 5.結局?

 このブログのこの記事も、かなりギリギリで書いています💦

 わたし、これほんと愚者の骨頂だと思うんですけど、いくつか陰謀論めいたこと信じていたりするんですね。「フラグ」がうんぬんとか、「言霊」がうんぬんとか、ギリギリでやると頭回るとか思っちゃってるんですよ。これら、全く根拠がないわけではなくて、時に自分の中で役に立ったりもしているのですが、ほんとうによくないのはこれらを言い訳にして物事をギリギリにしたり、信用を損なうことをしたり、なにかにつけて中途半端に終わらせてしまうことなんですよ。

 で、そんなんならなんでブログやってんだ!なんでXXXやってんだ!XXね!!

ってことになります(?)。というより、自分自身がそう思っているし、なにか説明できない恐怖みたいなのに包まれてしまいます。

 だったら、自分の為にブログを最大限に利用するのがよいはずです。

 ブログはweb上の日記であり、他人にみられるものです。その性質を利用するいくつかの、「これからの私のブログの使い方」について(完全に整理されたものではないけど)挙げていきます。

 あ、ちなみにこういう私事(特に「最近ブログの更新が遅くて~)をブログに書くとPV減るそうですが、元より少ないので無問題ですね。むしろ、今回は私の気持ちの吐露と抱負に「利用」してしまいましょう。

 ブログを利用すること

   では、わたしの短所と長所とブログというものの性質を踏まえて、わたしが自分の為になると思い、そしてこれからのブログ作りの1つの指針にしようと思っていることを3点掲げます。

1.人前で「目標」と「タスク」を宣言する

 私、きっと目立ちたがり屋なんですよ、結局。自分に自信がないからなにか人より長けているものを探して自慢してほめてもらいたい、そんな低級な欲求「承認欲求」がかなり強い人間なんだと思います。くそざこです。で、たまたま数学とかは自分にフィットして、今では本質的な意味でもある程度好きになりましたが、発端は「誰かに認めてもらうこと」「誰かに追いつくこと」「周りより抜きんでること」「誰かに見合うなにかを身に着けること」....そんな気持ちだったように思います。

 小中学校でやることって、努力の次第であっという間にある程度の力になったりします。特に、周りからの承認とは、その環境における相対的な能力値によって生じるため、わたしのように公立小中を通っていたものは、「周りに対して何か1つでも抜きんでた能力」を獲得することは比較的容易なのです。それこそ、自分が何が得意なのかみつけて進学していく前の段階ですからね。で、徐々に自分の得意分野における能力と周りの能力が近くなっていくんです。いや、もし何かの不運で自分に見合った社会的組織の一員になれなかったとしても関係ありません。注目すべきは広がる世界、日本中あるいは、世界中の同期になっていくはずです。だって、小中学校は自分の通学地区という狭い空間における世界を基本としていたのが、高校で県全体、大学で日本全体もしくは世界よ広がっていくんですから。もちろん、もっと早くから広い世界に飛び出す方もいますが、わたしはそうではありませんでした。

 世界が広がると、どの分野にも「自分よりできるやつ」がたくさんいることに気づかされます。それで中途半端になってしまうんですよ。もしくは元から中途半端だったのを、井戸の中の蛙のように勘違いしていたのかもしれません。

 だから、「その圧倒的な彼らに追いつこうという内なる闘志」が「承認」のために必要になってくるわけです。努力せなあかん。でも「内なる闘志」と「承認欲求」って正反対なんですよね、欲求の在りかが。前者の方が高級ですが、そのような「大きな目標」は、わたしのような心弱いものには難しい。だから、「大きな目標」に向けた「

小さな目標」を作る必要があります。「目標を達成するための区分的な目標」。でも、小刻みすぎて達成して得られる外的欲求を満たすものが少ない。

 そこで「ブログ」の登場です。目標をここに書くんです。自分を、不特定多数にさらけ出してしまうんです。PV数とか関係ありません、誰にみられるかわからないネットの海に目標とか自分の思いを流してしまう。恍惚。誰かが見ている。わたしみたいなのは、それだけで、やる気の入り方が変わってくると思うんです。達成したときの充足感も跳ね上がるはずです。...昔の数学と同じならば、こういった行動の繰り返しのうちにいつしかその物事が本質的に好きになる気がします。

2.自分で理解したことをなるべくすぐに記す

 うん。1.は気持ちが抑えきれず長くなったので、あとの2項目は手短に書きます。

なんであれ、自分で新しく学んで、「なるほど」、「大事だな」と感じたことはすぐにメモすること、ノートに取ること。これらは、理解の整理や定着においてとても大事ですよね。それとおなじ感覚でブログに理解したことをまとめるんです。すると、第三者の目を大なり小なり意識しますから、あとで見返したときなどによっり分かりやすい文章が記せる気がします。これはブログを使った良い学び方な気がします。

3.更新時間や日にちをなるべく統一する

 僕が時間にルーズなのは、やることの中身の具体性、先見性に欠けているからだと思います。そこで、更新する時間をなるべく一定にしようと思います。あと、定時更新は今まで同様1週間に一記事にして、その一記事のテーマはなるべく統一しようと思います。すなわち、目的ややることに具体性を持たせて、やる気を維持させようということです。ここで重要なことなんですが、

 ・あくまで「じばるどーね」=「ごった煮」なので、定期更新とは別に、不定期で様々なジャンルについて書いていく。

・定期更新は、時間があるときに内容を早めに作ってしまってもいいが、あえて公開時間を定め、その時間まで公開しないでおく。

 これらを前提として、定期更新の更新日を毎週月曜日の午前中にします。

 内容は「プログラムや情報学で学んだこと」とします。

 また、不定期ですが「クイズ」ジャンルの記事は比較的多めに書いていく(楽しいから)と宣言します。これは、土曜日の午前中に1か月1回以上更新します。

 

 年ごとの抱負・月ごとの抱負

  年ごとの目標=「大きな目標」、月ごとの目標=「小さな目標」ってかんじです。

 年度の目標は...やっぱもう少し整理させてください。

 で、今月の目標は、今月もう終わりかけなんですけども、一応初旬から自分の中で決めていました。3つあります。書きます。

  今月の目標

1.今月中にブログで10記事書く(いま6)

2.タイピングの練習を2週間以上連続で続ける(途切れたらアウト。いま、一回8日で途切れて5日目。もう途切れられない。)

3.AtCoder競技プログラミング)でいい加減に水色(レート1200以上)になり堂々とする(いま1115(やばい))

 

 結構きついですが、春休みですし、まともにすればどれも可能なはずです!

ここに書いたからな!!みんなに見られてんだ!!!!!うおおおーーー!!

 

 あ、あとAtCoderなどで解いた問題(簡単すぎるのは省く)はこのブログかTwitterに挙げていこうと思います。ほんとは#いいねされた数だけACするとかいう欲求満たす系精進したいんですが、フォロワーそこまで多くないので全然いいねされなそうなので今はやめときます。

 

 まとめ

  私の性格を踏まえると、ぶっちゃけ今回掲げたことをすべて完璧に自分がこなすとは思いません。でも、やれるだけやってやります。

 以上、くそ記事でした。読むな。

 

 関連記事

  ジャネーノ法則についてはこちらのクイズを参考にしてね。

yadrfu.hatenablog.com

いいブログの利用の仕方だと思います。

 

yadrfu.hatenablog.com