競え
※前スレ
C++ vs Rust
https://mevius.5ch.net/test/read.cgi/tech/1619219089/
C vs C++ vs Rust Part.2
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2021/12/15(水) 12:35:50.91ID:biBE4xC0103デフォルトの名無しさん
2021/12/19(日) 23:44:42.02ID:cDs+Q4pL 間違いがあれば俺が指摘修整してやるから安心しろ
おまえら雑魚はそれでいい
おまえら雑魚はそれでいい
104デフォルトの名無しさん
2021/12/20(月) 01:37:10.75ID:6C5yewwt おまえは間違ってるって主張だけだと数学100点の人と同じだぞ
せっかくだからどこが間違ってるか指摘してあげなよ
せっかくだからどこが間違ってるか指摘してあげなよ
105デフォルトの名無しさん
2021/12/20(月) 01:50:44.40ID:+mZvzmRI そいつらは前スレからそんな感じだから放置されてる
ガイジとかゲロとか汚などの言葉を好む
具体的なコードや具体的な指摘は出来ないダメな連中
ガイジとかゲロとか汚などの言葉を好む
具体的なコードや具体的な指摘は出来ないダメな連中
106デフォルトの名無しさん
2021/12/20(月) 13:09:41.04ID:Wae1ffBl プログラム勉強しはじめたんだけど、CとかC++よりもRUSTのほうがかっこよさげだからRUSTやってる
107デフォルトの名無しさん
2021/12/20(月) 17:47:27.57ID:WdsmvZWK 意識他界系かよ
108デフォルトの名無しさん
2021/12/20(月) 18:01:18.12ID:+DS1Ebvj CやLispからはじめるのが意識高い系
Rustからはじめるのはカッコつけたいだけの単なる無知
Rustからはじめるのはカッコつけたいだけの単なる無知
109デフォルトの名無しさん
2021/12/20(月) 18:21:17.98ID:k0WQlEJJ C++から始めるのは何系?
110デフォルトの名無しさん
2021/12/20(月) 18:34:34.79ID:LHZmynrD CがあるのにC++から始めるひとはガイジ系
111デフォルトの名無しさん
2021/12/20(月) 18:37:40.57ID:WdsmvZWK 10年早い系
112デフォルトの名無しさん
2021/12/20(月) 19:11:56.15ID:S0D0uK3y ウッホウッホホ、マウンテンゴリラです。得意なのはドラミングで毎日ドコドコやってます
113デフォルトの名無しさん
2021/12/20(月) 19:19:22.55ID:wggVCSJj >>108
なんでrustからだとあかんの?
なんでrustからだとあかんの?
114デフォルトの名無しさん
2021/12/20(月) 19:54:01.15ID:ceMzU2Ib マルチパラダイムだからでは。
115デフォルトの名無しさん
2021/12/20(月) 20:10:25.93ID:wggVCSJj >>114
よく知りもせんなら黙ってろや
よく知りもせんなら黙ってろや
116デフォルトの名無しさん
2021/12/20(月) 20:22:01.28ID:qir2xW7W 最近c++勉強始めたんだが、cとかmapも使えないじゃん
どうしてんの?
どうしてんの?
117デフォルトの名無しさん
2021/12/20(月) 20:29:53.40ID:ceMzU2Ib mapを作るための言語がCだから。
118デフォルトの名無しさん
2021/12/20(月) 21:00:54.00ID:MpI5dMic RustはコンパイラもライブラリもRustで書かれているね
119デフォルトの名無しさん
2021/12/20(月) 21:10:35.52ID:WdsmvZWK >>116
昔はアルゴリズムの教本を参考にして全部1からつくってた
昔はアルゴリズムの教本を参考にして全部1からつくってた
120デフォルトの名無しさん
2021/12/20(月) 21:56:05.64ID:MpI5dMic 今も必要があれば車輪の再発明をする能力を持つ人と持たない人にプログラマーは二分される
前者は新たな枠組みを作ることも可能な生産者
後者は既存の枠組みを使うだけの消費者
前者は新たな枠組みを作ることも可能な生産者
後者は既存の枠組みを使うだけの消費者
121デフォルトの名無しさん
2021/12/20(月) 23:37:11.43ID:qir2xW7W 俺には検討もつかんわ
所詮俺は消費者か…
所詮俺は消費者か…
122デフォルトの名無しさん
2021/12/20(月) 23:37:21.66ID:qir2xW7W 見当
123デフォルトの名無しさん
2021/12/20(月) 23:47:18.19ID:ceMzU2Ib コンシューマーって言えばカッコよくなるよ。
124デフォルトの名無しさん
2021/12/21(火) 02:18:43.99ID:ukVjEMSL プロデューサーとコンシューマーと呼ぶと両方存在して初めて意味を持ちそうな感じがするな
125デフォルトの名無しさん
2021/12/21(火) 02:38:28.55ID:XzF1jwer この場合の生産者は、制作者(プロデューサー)ではなくて創造者(クリエイター)の方が近い
126デフォルトの名無しさん
2021/12/21(火) 08:29:08.29ID:J9NEE3Tt もっともらしく言ってるけど
新たな枠組みを作ることができるかどうかに
車輪の再発明をする能力は関係ないよ
新たな枠組みを作ることができるかどうかに
車輪の再発明をする能力は関係ないよ
127デフォルトの名無しさん
2021/12/21(火) 08:37:17.38ID:91RXJaij プログラミングにおいて車輪の再発明すら出来ない人が
プログラミングにおいて新たな枠組みを作るのは無理
プログラミングにおいて新たな枠組みを作るのは無理
128デフォルトの名無しさん
2021/12/21(火) 08:59:49.41ID:1P8ZKx5y ザッカーバーグとかツールレベルでいえばあるもの使ってただけだがな。
129デフォルトの名無しさん
2021/12/21(火) 09:42:52.55ID:oIl64W+t クイックソートくらいは自作してみたほうがいい
最初混乱するだろうけど、ああなるほど!となった時に必ず経験値に加算される筈だ
最初混乱するだろうけど、ああなるほど!となった時に必ず経験値に加算される筈だ
130デフォルトの名無しさん
2021/12/21(火) 10:37:29.68ID:91RXJaij >>128
そりゃ彼はプログラミングにおいて新たな枠組みを作ったわけではないからな
そりゃ彼はプログラミングにおいて新たな枠組みを作ったわけではないからな
131デフォルトの名無しさん
2021/12/21(火) 12:47:53.03ID:ukVjEMSL 新たな枠組みって例えば何?
フレームワークのことではなさそうだけど
フレームワークのことではなさそうだけど
132デフォルトの名無しさん
2021/12/21(火) 13:12:13.10ID:fLSFmYOm 例えば画像データの取り扱いでbitmapをそのまま処理していたような時代にpngやjpgなどのアルゴリズムをはじめて考え出して
実装したようなプログラマが新たな枠組みを作ることが出来る人
既存のライブラリ使って画像処理や表示のアプリを実装しているようなプログラマが枠組みを使うだけの人
実装したようなプログラマが新たな枠組みを作ることが出来る人
既存のライブラリ使って画像処理や表示のアプリを実装しているようなプログラマが枠組みを使うだけの人
133デフォルトの名無しさん
2021/12/21(火) 13:13:16.14ID:91RXJaij もちろん例としてプログラミングのフレームワークでもいいんじゃね?
例えばそのザッカーバーグの例ならば
Facebook社はプログラミングにおいて新たな枠組みとして世間にも広まるほどのReactを作った
一方でザッカーバーグ自体はReactを今から車輪の再発明すらできないしプログラミングにおいて新たな枠組みを作れないだろう
例えばそのザッカーバーグの例ならば
Facebook社はプログラミングにおいて新たな枠組みとして世間にも広まるほどのReactを作った
一方でザッカーバーグ自体はReactを今から車輪の再発明すらできないしプログラミングにおいて新たな枠組みを作れないだろう
134デフォルトの名無しさん
2021/12/21(火) 14:51:21.09ID:SKVIwMRv 枠組みに限らず何か新しいもの自力で作るには
その対象レイヤーのものを作れる能力は必要
それは当たり前
ザッカーバーグだって掲示板システムを実装する能力があったからFacebookを作れたわけだが
それを「車輪の再発明する能力」と呼ぶのかどうか
「新しい枠組み」と「車輪の再発明をする能力」の定義が曖昧すぎて中身がない
その対象レイヤーのものを作れる能力は必要
それは当たり前
ザッカーバーグだって掲示板システムを実装する能力があったからFacebookを作れたわけだが
それを「車輪の再発明する能力」と呼ぶのかどうか
「新しい枠組み」と「車輪の再発明をする能力」の定義が曖昧すぎて中身がない
135デフォルトの名無しさん
2021/12/21(火) 14:53:33.71ID:SKVIwMRv 結局のところ
「低レイヤーの開発をするには低レイヤーの実装能力が必要」という主張でしかない
「低レイヤーの開発をするには低レイヤーの実装能力が必要」という主張でしかない
136デフォルトの名無しさん
2021/12/21(火) 15:02:25.60ID:91RXJaij そこは定義でもめるから深入りしない
例えば例に挙げたReactは自分の観点からは低レイヤーではなく高レイヤー
結局これでいいかね?
各分野のプログラミングにおいて車輪の再発明すら出来ない人が
その分野のプログラミングにおいて新たな枠組みを作るのは無理
例えば例に挙げたReactは自分の観点からは低レイヤーではなく高レイヤー
結局これでいいかね?
各分野のプログラミングにおいて車輪の再発明すら出来ない人が
その分野のプログラミングにおいて新たな枠組みを作るのは無理
137デフォルトの名無しさん
2021/12/21(火) 16:17:27.88ID:ukVjEMSL 車輪の再発明って何
自身で模倣できる程度には理解しているということ?
自身で模倣できる程度には理解しているということ?
138デフォルトの名無しさん
2021/12/21(火) 17:55:52.77ID:dNZ8oAHl レイヤーは相対的なものだよ
低レイヤーで通じないなら下位レイヤーとでも言おうか
Reactのユーザーから見ればReactそのものの開発は下位レイヤー
Reactを作るために下位レイヤーのJavaScriptエンジンやレンダリングエンジンを再発明できる能力が必要か?
低レイヤーで通じないなら下位レイヤーとでも言おうか
Reactのユーザーから見ればReactそのものの開発は下位レイヤー
Reactを作るために下位レイヤーのJavaScriptエンジンやレンダリングエンジンを再発明できる能力が必要か?
139デフォルトの名無しさん
2021/12/21(火) 19:16:57.14ID:91RXJaij 話はシンプル
それぞれの分野で見ればよい
Reactの分野だったら
『自分でウェブフロントフレームワークを簡易なものでよいから作ったことあるか?あるいは作れるか?』
これだけの話
つまりReactの開発者たちと同じような立ち位置に立てるプログラマーなのか、
それともReactの消費者としてユーザーの立場のプログラマーなのか、の違い
それぞれの分野で見ればよい
Reactの分野だったら
『自分でウェブフロントフレームワークを簡易なものでよいから作ったことあるか?あるいは作れるか?』
これだけの話
つまりReactの開発者たちと同じような立ち位置に立てるプログラマーなのか、
それともReactの消費者としてユーザーの立場のプログラマーなのか、の違い
140デフォルトの名無しさん
2021/12/21(火) 21:33:34.81ID:FgftkvCZ まとめると
「新しいウェブフロントフレームワークを作るには
ウェブフロントフレームワークを作る能力が必要」
そりゃそうだ
話はシンプルシンプル
「新しいウェブフロントフレームワークを作るには
ウェブフロントフレームワークを作る能力が必要」
そりゃそうだ
話はシンプルシンプル
141デフォルトの名無しさん
2021/12/21(火) 22:16:57.85ID:B7hTDXPV なんだよこれ遅っせーなー
意味分かんねーんだよこの挙動
俺のほうがもっとうまく作れる
意味分かんねーんだよこの挙動
俺のほうがもっとうまく作れる
142デフォルトの名無しさん
2021/12/21(火) 23:02:50.37ID:BV9oeByN 消費者プログラマーは色んな仕組みをわかっていなかったり理解できなかったりする人が多いね
そうなると車輪の再発明すらできないし車輪の改良もできない
もちろん車輪に代わる新たな仕組みを作り出すこともできない
そうなると車輪の再発明すらできないし車輪の改良もできない
もちろん車輪に代わる新たな仕組みを作り出すこともできない
143デフォルトの名無しさん
2021/12/21(火) 23:19:52.13ID:aVQrTCZW >>138
これ本気で言ってるのか
これ本気で言ってるのか
144デフォルトの名無しさん
2021/12/21(火) 23:37:27.40ID:BV9oeByN 元の話はmapの実装方法がわからない、だから、もっと深刻な状況なのか
プログラミングする上での基本的なことは
車輪の再発明であろうと自分でやってみて体験していくべき
プログラミングする上での基本的なことは
車輪の再発明であろうと自分でやってみて体験していくべき
145デフォルトの名無しさん
2021/12/22(水) 00:26:44.89ID:hlL8iDYx 習熟のために必ずしも車輪の再発明が必要であるわけではないでしょ
146デフォルトの名無しさん
2021/12/22(水) 03:14:26.40ID:zUrn+LAM 発明する必要はないけど何もないところから自分の力だけで車輪を組み立てられるようにはなっておいた方が良い
147デフォルトの名無しさん
2021/12/22(水) 04:06:02.73ID:3N0TjzPj Cをやるとそういう力が身に付く
148デフォルトの名無しさん
2021/12/22(水) 13:40:20.98ID:88lOWKJS 「フロントフレームワーク」なんて言い方するのかとググったら、まぁまぁ居たわ
149デフォルトの名無しさん
2021/12/22(水) 14:48:58.75ID:cbZXpGCW IPアドレスの正規表現を再発明してるやつがいたけど
ああいうのが"新しい枠組みを作ることも可能な生産者"だったのかw
ああいうのが"新しい枠組みを作ることも可能な生産者"だったのかw
150デフォルトの名無しさん
2021/12/22(水) 15:12:06.24ID:ACMGo5I0 IPアドレスの仕組みも正規表現も別に目新しいものではないのでは?
何か特別な表現手法とかを導入する余地って残されていたか?
何か特別な表現手法とかを導入する余地って残されていたか?
151デフォルトの名無しさん
2021/12/22(水) 15:54:00.21ID:EC7ouo8z 正規表現とか言ってもただの文字列だからな
数式やアルゴリズムに落とし込めないもので再発明も何も手の出しようがないだろ
数式やアルゴリズムに落とし込めないもので再発明も何も手の出しようがないだろ
152デフォルトの名無しさん
2021/12/22(水) 16:28:01.11ID:fS3VtBnk 使ってる言葉を自分なりに定義できないやつは普段物事を深く考えてない
知性の程度を簡単に測れる物差し
知性の程度を簡単に測れる物差し
153デフォルトの名無しさん
2021/12/22(水) 16:32:42.08ID:d0MJTsFe つまり…?
154デフォルトの名無しさん
2021/12/22(水) 18:46:01.74ID:+56mJT2x155デフォルトの名無しさん
2021/12/22(水) 19:48:14.08ID:8fPxaOZD 正規表現は文字列の集合を表すだけですよ。
156デフォルトの名無しさん
2021/12/22(水) 20:06:24.06ID:ZbLVUWay ある正規言語に対応する文字列やろ
157デフォルトの名無しさん
2021/12/22(水) 20:08:22.67ID:NbFNi3kC ただの検索や置換のためだけのメタ言語だよ
問題記述能力はない
問題記述能力はない
158デフォルトの名無しさん
2021/12/22(水) 22:30:17.60ID:kJHwXG4U 問題記述能力?
159デフォルトの名無しさん
2021/12/22(水) 23:57:26.44ID:oj/5QvFT >IPアドレスの正規表現を再発明してるやつがいたけど
再発明って具体的にどういうことやってたことを言っているんだろ
再発明って具体的にどういうことやってたことを言っているんだろ
160デフォルトの名無しさん
2021/12/22(水) 23:58:38.64ID:WkDs1ZLi そのケースはアルゴリズムではないな
一般的に自分で一から作れる人はその時々に応じて最適なアルゴリズムを見つけ出すだろう
一般的に自分で一から作れる人はその時々に応じて最適なアルゴリズムを見つけ出すだろう
161デフォルトの名無しさん
2021/12/23(木) 00:18:12.96ID:jzS6xQy/ 何がアルゴリズムで何がアルゴリズムでないか
ちゃんと境界値テストできてる?
ちゃんと境界値テストできてる?
162デフォルトの名無しさん
2021/12/23(木) 00:20:51.73ID:HHXdPx7l 数式はアルゴリズムなのか?
163デフォルトの名無しさん
2021/12/23(木) 00:32:50.26ID:GoKXBRn5 俺がすごいと思ったらすごいというのをいかに客観的評価のように見せるか議論しているようにしか見えない
164デフォルトの名無しさん
2021/12/23(木) 00:47:38.83ID:1+zdX/p3165デフォルトの名無しさん
2021/12/23(木) 08:21:29.85ID:zbE03cOE166デフォルトの名無しさん
2021/12/23(木) 10:21:26.98ID:jJ3uH/7E 無限大を数値計算で扱うために優秀なソフトエンジニア達の手によって、例えば離散フーリエ変換や離散ウェーブレット変換などのアルゴリズムが工夫され考え出された
これが新しい枠組みを作り出すということ
これが新しい枠組みを作り出すということ
167デフォルトの名無しさん
2021/12/23(木) 10:33:51.13ID:uWdVPWrO168デフォルトの名無しさん
2021/12/23(木) 11:37:52.36ID:Gjq2t2pD >>167
FTは無限大集合を扱っている訳では無いだろ。実数とか扱えないし。
FTは無限大集合を扱っている訳では無いだろ。実数とか扱えないし。
169デフォルトの名無しさん
2021/12/23(木) 12:01:15.99ID:l46o0/Jm 周期信号のフーリエ級数展開なら有限だけど連続信号を扱うなら無限積分の計算が必要
FTは無限積分を数値計算するため分割統治のバタフライ演算に落とし込んで更に演算量を抑えるため各種のアルゴリズムが考案されてる
FTは無限積分を数値計算するため分割統治のバタフライ演算に落とし込んで更に演算量を抑えるため各種のアルゴリズムが考案されてる
170デフォルトの名無しさん
2021/12/23(木) 12:32:25.74ID:GoKXBRn5 で、新しい枠組みを作り出すことが C vs C++ vs Rust にどう関わってくるの
171デフォルトの名無しさん
2021/12/23(木) 12:46:22.58ID:l46o0/Jm 枠組みを作ることは凡人には無理
殆どは枠組みを使う人
ただ枠組みの仕組みを知らないと使うことも出来ない
殆どは枠組みを使う人
ただ枠組みの仕組みを知らないと使うことも出来ない
172デフォルトの名無しさん
2021/12/23(木) 12:56:14.10ID:GHRrX/7/ 最早スレチの話題に突っ込んで悪いけど、無限積分を回避できている気になっているのは気のせいであって、バタフライ演算とか関係ないからね(笑)
173デフォルトの名無しさん
2021/12/23(木) 17:57:47.72ID:NwYcCv97 以前に皆さま方からアドバイスをいただいて
『足し算のみで素数列を生成するジェネリックなイテレータの実装』
を当時O(N^3)という酷さでしたが、このたびほぼ O(N) の新たなアルゴリズムと実装が出来ましたのでご報告します
足し算の総回数を O(N log log N) すなわちほぼ O(N) 近くにすることに成功しました
具体的には 1億(=10^8) までの素数生成に必要とする 足し算の総回数が 2.5億回 とリニアになりました
前回と異なりメモ化をしていますがこちらも工夫により配列の長さを O(√N / log N) に抑えることに成功しました
具体的には 1億(=10^8) までの素数生成に必要とする 配列の長さが 1231 と非常に小さな領域のみで実現できました
10^kまでの素数を順に生成時の足し算の総回数 O(N log log N)
10^1 4.70×10^1=47
10^2 2.03×10^2=203
10^3 1.90×10^3=1903
10^4 1.95×10^4=19508
10^5 2.12×10^5=212715
10^6 2.27×10^6=2278220
10^7 2.41×10^7=24148110
10^8 2.54×10^8=254082528
10^kまでの素数を順に生成時の配列の長さ O(√N / log N)
10^1 4
10^2 6
10^3 13
10^4 27
10^5 67
10^6 170
10^7 448
10^8 1231
メモリ使用もこの程度の少なさで
足し算を2.5億回とその比較だけで1億までの全ての素数を順に出力できるようになりました
このスレは数学が得意な方々が多いようなのでご検証よろしくお願いします
『足し算のみで素数列を生成するジェネリックなイテレータの実装』
を当時O(N^3)という酷さでしたが、このたびほぼ O(N) の新たなアルゴリズムと実装が出来ましたのでご報告します
足し算の総回数を O(N log log N) すなわちほぼ O(N) 近くにすることに成功しました
具体的には 1億(=10^8) までの素数生成に必要とする 足し算の総回数が 2.5億回 とリニアになりました
前回と異なりメモ化をしていますがこちらも工夫により配列の長さを O(√N / log N) に抑えることに成功しました
具体的には 1億(=10^8) までの素数生成に必要とする 配列の長さが 1231 と非常に小さな領域のみで実現できました
10^kまでの素数を順に生成時の足し算の総回数 O(N log log N)
10^1 4.70×10^1=47
10^2 2.03×10^2=203
10^3 1.90×10^3=1903
10^4 1.95×10^4=19508
10^5 2.12×10^5=212715
10^6 2.27×10^6=2278220
10^7 2.41×10^7=24148110
10^8 2.54×10^8=254082528
10^kまでの素数を順に生成時の配列の長さ O(√N / log N)
10^1 4
10^2 6
10^3 13
10^4 27
10^5 67
10^6 170
10^7 448
10^8 1231
メモリ使用もこの程度の少なさで
足し算を2.5億回とその比較だけで1億までの全ての素数を順に出力できるようになりました
このスレは数学が得意な方々が多いようなのでご検証よろしくお願いします
174デフォルトの名無しさん
2021/12/23(木) 18:08:00.97ID:NwYcCv97 今回は読みやすいようにループで記述しました
impl<T> Iterator for 素数生成Iterator<T>
where T: Copy + num::Zero + num::One + num::CheckedAdd + std::cmp::PartialOrd,
{
type Item = T;
fn next(&mut self) -> Option<T> {
'次候補: loop {
self.新素数 = self.新素数.checked_add(&T::one())?;
if self.新素数 == self.倍数[self.上限] {
self.上限 += 1;
if self.子.is_some() {
self.素数.push(self.子.as_mut()?.next()?);
}
self.倍数.push(二乗(self.素数[self.上限]));
}
for index in 1..self.上限 {
while self.倍数[index] != T::zero() && self.倍数[index] < self.新素数 {
self.倍数[index] = self.倍数[index].checked_add(&self.素数[index]).unwrap_or(T::zero());
}
if self.倍数[index] == self.新素数 {
continue '次候補;
}
}
break;
}
if self.子.is_none() {
self.素数.push(self.新素数);
}
Some(self.新素数)
}
}
impl<T> Iterator for 素数生成Iterator<T>
where T: Copy + num::Zero + num::One + num::CheckedAdd + std::cmp::PartialOrd,
{
type Item = T;
fn next(&mut self) -> Option<T> {
'次候補: loop {
self.新素数 = self.新素数.checked_add(&T::one())?;
if self.新素数 == self.倍数[self.上限] {
self.上限 += 1;
if self.子.is_some() {
self.素数.push(self.子.as_mut()?.next()?);
}
self.倍数.push(二乗(self.素数[self.上限]));
}
for index in 1..self.上限 {
while self.倍数[index] != T::zero() && self.倍数[index] < self.新素数 {
self.倍数[index] = self.倍数[index].checked_add(&self.素数[index]).unwrap_or(T::zero());
}
if self.倍数[index] == self.新素数 {
continue '次候補;
}
}
break;
}
if self.子.is_none() {
self.素数.push(self.新素数);
}
Some(self.新素数)
}
}
175デフォルトの名無しさん
2021/12/23(木) 18:17:16.76ID:NwYcCv97 上述に「子」とあるのはメモリ節約のためのテクニックで
「子」と「孫」を再帰的に利用しているためです
「自分」だけで必要なメモリをNとすると
「子」を利用することでメモリが√Nで済むように設計しました
また、 self.上限 が配列の長さで
self.新素数 が1億(=10^8)まで進んだ時点で self.上限 が 1231 です
self.上限 が更新された時のみ、つまり1億までで1231回だけ
コードにあるように以下の二乗する関数が呼ばれます
fn 二乗<T>(n: T) -> T
where T: Copy + num::Zero + num::One + num::CheckedAdd + std::cmp::PartialOrd,
{
let mut count = T::one();
let mut result = n;
while result != T::zero() && count < n {
count = count.checked_add(&T::one()).unwrap();
result = result.checked_add(&n).unwrap_or(T::zero());
}
result
}
「子」と「孫」を再帰的に利用しているためです
「自分」だけで必要なメモリをNとすると
「子」を利用することでメモリが√Nで済むように設計しました
また、 self.上限 が配列の長さで
self.新素数 が1億(=10^8)まで進んだ時点で self.上限 が 1231 です
self.上限 が更新された時のみ、つまり1億までで1231回だけ
コードにあるように以下の二乗する関数が呼ばれます
fn 二乗<T>(n: T) -> T
where T: Copy + num::Zero + num::One + num::CheckedAdd + std::cmp::PartialOrd,
{
let mut count = T::one();
let mut result = n;
while result != T::zero() && count < n {
count = count.checked_add(&T::one()).unwrap();
result = result.checked_add(&n).unwrap_or(T::zero());
}
result
}
176デフォルトの名無しさん
2021/12/23(木) 18:20:15.44ID:NwYcCv97 fn main() {
assert_eq!(vec![2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127], 素数生成::<i8>().collect::<Vec<_>>());
assert_eq!(65521, 素数生成::<u16>().last().unwrap());
assert_eq!(78498, 素数生成::<u32>().take_while(|&p| p < 1000000).count());
}
fn 素数生成<T>() -> 素数生成Iterator<T> where T: Copy + num::One + num::CheckedAdd {
let 孫 = 素数生成Iterator::<T>::new(None);
let 子 = 素数生成Iterator::<T>::new(Some(孫));
素数生成Iterator::<T>::new(Some(子))
}
struct 素数生成Iterator<T> {
素数: Vec<T>,
倍数: Vec<T>,
新素数: T,
上限: usize,
子: Option<Box<Self>>,
}
impl<T> 素数生成Iterator<T> where T: Copy + num::One + num::CheckedAdd {
fn new(子指定: Option<Self>) -> Self {
let three = T::one().checked_add(&T::one()).unwrap().checked_add(&T::one()).unwrap();
Self {
素数: vec![T::one()],
倍数: vec![three],
新素数: T::one(),
上限: 0,
子: 子指定.map(|子| Box::new(子)),
}
}
}
assert_eq!(vec![2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127], 素数生成::<i8>().collect::<Vec<_>>());
assert_eq!(65521, 素数生成::<u16>().last().unwrap());
assert_eq!(78498, 素数生成::<u32>().take_while(|&p| p < 1000000).count());
}
fn 素数生成<T>() -> 素数生成Iterator<T> where T: Copy + num::One + num::CheckedAdd {
let 孫 = 素数生成Iterator::<T>::new(None);
let 子 = 素数生成Iterator::<T>::new(Some(孫));
素数生成Iterator::<T>::new(Some(子))
}
struct 素数生成Iterator<T> {
素数: Vec<T>,
倍数: Vec<T>,
新素数: T,
上限: usize,
子: Option<Box<Self>>,
}
impl<T> 素数生成Iterator<T> where T: Copy + num::One + num::CheckedAdd {
fn new(子指定: Option<Self>) -> Self {
let three = T::one().checked_add(&T::one()).unwrap().checked_add(&T::one()).unwrap();
Self {
素数: vec![T::one()],
倍数: vec![three],
新素数: T::one(),
上限: 0,
子: 子指定.map(|子| Box::new(子)),
}
}
}
177デフォルトの名無しさん
2021/12/23(木) 18:29:41.75ID:NwYcCv97 コードは以上です
今回はitertools::unfold()を用いなかったため、それにより省略できていた、
「イテレータ用構造体の宣言」「その初期化」「そのIteratorトレイト実装宣言」
などが今回は必要となりコードがその分だけ長くなっていますが
イテレータの実装本体部分は>>174のみです
足し算の総回数が O(N log log N) 例: 素数を1億までで2.5億回
メモリは配列の長さが O(√N / log N) 例: 素数を1億までで長さ1231使用
これらを足し算のみで実現できています
どうぞご検証よろしくお願いします
今回はitertools::unfold()を用いなかったため、それにより省略できていた、
「イテレータ用構造体の宣言」「その初期化」「そのIteratorトレイト実装宣言」
などが今回は必要となりコードがその分だけ長くなっていますが
イテレータの実装本体部分は>>174のみです
足し算の総回数が O(N log log N) 例: 素数を1億までで2.5億回
メモリは配列の長さが O(√N / log N) 例: 素数を1億までで長さ1231使用
これらを足し算のみで実現できています
どうぞご検証よろしくお願いします
178デフォルトの名無しさん
2021/12/23(木) 18:41:40.03ID:eB9sLMVm 嫌われ者Rusterのウザウザ全文貼り付け、見るのも嫌になる自己満足オナニー
179デフォルトの名無しさん
2021/12/23(木) 18:47:57.52ID:y6QdIUGa なんかやたら足し算のみで、って強調してるけど、
アルゴリズムはエラトステネスの篩だよね?
そう言ってくれたほうが理解しやすいよ
Rustはまだあんま良くわかってないのでコードは参考になるかも
でもテストケースに127が入ってるのはおかしくない?
アルゴリズムはエラトステネスの篩だよね?
そう言ってくれたほうが理解しやすいよ
Rustはまだあんま良くわかってないのでコードは参考になるかも
でもテストケースに127が入ってるのはおかしくない?
180デフォルトの名無しさん
2021/12/23(木) 18:49:15.20ID:y6QdIUGa あ、おかしくなかった
すまん
すまん
181デフォルトの名無しさん
2021/12/23(木) 19:25:25.17ID:2KeIelt0 アルゴリズムに興味がある場合はCが読みやすいということがよくわかった
182デフォルトの名無しさん
2021/12/23(木) 20:59:20.34ID:QAvlUc5m 1億までの素数を全て求めるのが2.5億回の足し算だけで出来るものなのか??
メモリもエラトステネスだと1億必要だよな?
メモリもエラトステネスだと1億必要だよな?
183デフォルトの名無しさん
2021/12/23(木) 23:06:13.63ID:MjSWMWRR 一億たって100メガにすぎませんからね。
184デフォルトの名無しさん
2021/12/23(木) 23:52:41.64ID:NwYcCv97 >>182
1億回の素数判定を個別に考えると平均2.5回の足し算となりもちろん無理です
そこで過去の判定時で用いた足し算の結果を後の判定時に用いる方法で
結果的に平均2.5回の足し算で済ませています
また、単純にエラトステネスのふるいでは1億の長さの配列が必要となりますが
まず時間と空間を逆転させることで必要となる配列の長さを減らしています
さらに再帰的に子と孫のイテレータを活用することで
>>173の表のように1億(=10^8)まで判定時で配列の長さ1231に抑えています
その時点で子と孫では配列の長さ27となっています
>>183
そんなO(N)のペースでメモリを使用していくのはいずれ限界もありますし
メモリキャッシュヒットの観点からも望ましくないと思います
さらに今回は小さい方から順に素数を返すイテレータです
イテレータ利用者は1億を超えて素数を利用するかもしれませんし
逆にもっと少ない小さい数のみ利用するかもしれません
最初に上限が1億など決まって開始する古典的エラトステネスのふるいでは上手くいかないのです
1億回の素数判定を個別に考えると平均2.5回の足し算となりもちろん無理です
そこで過去の判定時で用いた足し算の結果を後の判定時に用いる方法で
結果的に平均2.5回の足し算で済ませています
また、単純にエラトステネスのふるいでは1億の長さの配列が必要となりますが
まず時間と空間を逆転させることで必要となる配列の長さを減らしています
さらに再帰的に子と孫のイテレータを活用することで
>>173の表のように1億(=10^8)まで判定時で配列の長さ1231に抑えています
その時点で子と孫では配列の長さ27となっています
>>183
そんなO(N)のペースでメモリを使用していくのはいずれ限界もありますし
メモリキャッシュヒットの観点からも望ましくないと思います
さらに今回は小さい方から順に素数を返すイテレータです
イテレータ利用者は1億を超えて素数を利用するかもしれませんし
逆にもっと少ない小さい数のみ利用するかもしれません
最初に上限が1億など決まって開始する古典的エラトステネスのふるいでは上手くいかないのです
185デフォルトの名無しさん
2021/12/24(金) 00:05:23.52ID:jmk0MHfo キャッシュヒット率の話するならベンチマークとってくれ
186デフォルトの名無しさん
2021/12/24(金) 00:12:47.34ID:1YPq+lkD わざわざ決まってる数列を順番に出力するイテレータ書くのにそんな記述が必要になるのか
ちょっと普通のループでいいからC言語で書いてみてよ
ちょっと普通のループでいいからC言語で書いてみてよ
187デフォルトの名無しさん
2021/12/24(金) 00:19:39.24ID:HWkip0+R188デフォルトの名無しさん
2021/12/24(金) 19:37:12.56ID:MpuWLPBj イテレータにすると、プログラミングの方向が変わるんですよ。
詳細を未来に先送りできるんです。
伝統ある手続き型の手法では、システムやライブラリを書く人が詳細を実装し、使う人は大まかな指示を出しましたよね。
イテレータ手法は、未来に詳細を決定する。
つまり使う人が細かいことを決める事になるんです。
そこらへんの詳しい話は、書籍クリーンアーキテクチャに載ってます。
この本に書かれてることがすべて正しいとは言いませんが、正しいことにしろ間違ってることにしろ、読んでおいて損はないです。
詳細を未来に先送りできるんです。
伝統ある手続き型の手法では、システムやライブラリを書く人が詳細を実装し、使う人は大まかな指示を出しましたよね。
イテレータ手法は、未来に詳細を決定する。
つまり使う人が細かいことを決める事になるんです。
そこらへんの詳しい話は、書籍クリーンアーキテクチャに載ってます。
この本に書かれてることがすべて正しいとは言いませんが、正しいことにしろ間違ってることにしろ、読んでおいて損はないです。
189デフォルトの名無しさん
2021/12/24(金) 19:43:08.10ID:jmk0MHfo イテレータ特有の話と言うより遅延評価全般の話に読めるが
190デフォルトの名無しさん
2021/12/24(金) 20:57:48.40ID:4EcCA1ju イテレータ万能説を唱えて長文するガチキチおじさんwww
yieldはgeneratorをレイトバインド
for(range)はiteratorをレイトバインド
async/awaitはfutrueをレイトバインド
詳細を未来に先送り!キリッw
yieldはgeneratorをレイトバインド
for(range)はiteratorをレイトバインド
async/awaitはfutrueをレイトバインド
詳細を未来に先送り!キリッw
191デフォルトの名無しさん
2021/12/24(金) 21:06:12.59ID:MpuWLPBj >>190
さあご一緒に、キリツ!
さあご一緒に、キリツ!
192デフォルトの名無しさん
2021/12/24(金) 21:28:57.48ID:fTLW+5qu レイト「バインド」?
193デフォルトの名無しさん
2021/12/24(金) 21:44:54.12ID:cMhJNtck クリーンアーキテクチャを出してるから遅延評価のことじゃなく
IoCの一例としての高階関数のことを言いたいんじゃないかな?
IoCの一例としての高階関数のことを言いたいんじゃないかな?
194デフォルトの名無しさん
2021/12/24(金) 22:01:56.18ID:piC+XKnR 昔は局所化して先送りにできることは素晴らしいことだと思ってた
でも最近そんなのは些末な事で、無能な働き者が気にすることだったなと考えを改めた
木を見て森を見ずと言うべきか
でも最近そんなのは些末な事で、無能な働き者が気にすることだったなと考えを改めた
木を見て森を見ずと言うべきか
195デフォルトの名無しさん
2021/12/24(金) 22:55:30.83ID:UVQKl71H >>188
ある意味その考え方も正しいかもしれませんが
イテレータは例えば大ざっぱに分けても5種類はあるので
自分が作る部分がどの部分かによってその立場も変わると思います
(1) 発信イテレータ … >>174で示しました素数生成、レンジ(0..n)、配列やVecに対するiter()などチェーンでは先頭に来るもの
(2) 仲介イテレータ … map()、filter()、enumerate()などチェーンでは中間に来るもの
(3) 受信イテレータ … find()、fold()、collect()などチェーンでは最後に来るもの
(4) 合成イテレータ … chain()、zip()、merge()など複数のイテレータを入力とするもの
(5) 創造イテレータ … unfold()などイテレータを生み出す汎用イテレータ
とりあえず(4)(5)は置いとくにしても自分が作る部分は用途によって(1)か(2)か(3)と変わるため大きく立場も異なります
>>189
一般的に遅延評価による先送りといえば主役はクロージャですね
上述したイテレータを作り出すunfold()もクロージャを渡すことで成立しています
>>190
futureは「未来に先送り」ではなく「未来を先取り」と捉えたほうがよくないでしょうか
そして遅延評価というよりも並行並列評価する形になりますね
したがって今回の話には適さないかなと思います
ある意味その考え方も正しいかもしれませんが
イテレータは例えば大ざっぱに分けても5種類はあるので
自分が作る部分がどの部分かによってその立場も変わると思います
(1) 発信イテレータ … >>174で示しました素数生成、レンジ(0..n)、配列やVecに対するiter()などチェーンでは先頭に来るもの
(2) 仲介イテレータ … map()、filter()、enumerate()などチェーンでは中間に来るもの
(3) 受信イテレータ … find()、fold()、collect()などチェーンでは最後に来るもの
(4) 合成イテレータ … chain()、zip()、merge()など複数のイテレータを入力とするもの
(5) 創造イテレータ … unfold()などイテレータを生み出す汎用イテレータ
とりあえず(4)(5)は置いとくにしても自分が作る部分は用途によって(1)か(2)か(3)と変わるため大きく立場も異なります
>>189
一般的に遅延評価による先送りといえば主役はクロージャですね
上述したイテレータを作り出すunfold()もクロージャを渡すことで成立しています
>>190
futureは「未来に先送り」ではなく「未来を先取り」と捉えたほうがよくないでしょうか
そして遅延評価というよりも並行並列評価する形になりますね
したがって今回の話には適さないかなと思います
196デフォルトの名無しさん
2021/12/24(金) 23:02:03.16ID:UVQKl71H >>186
> わざわざ決まってる数列を順番に出力するイテレータ書くのにそんな記述が必要になるのか
決まってる数列ではなく毎回算出するんですよ
記述については各々のイテレータはそれぞれ何らかの構造体にすぎないので >>176に示しましたように
「(a) イテレータとなる構造体の型宣言」「(b) その構造体の初期値定義 new()」「(c) 今回は自分と子と孫がいるためその関係記述」
があってようやく、>174に示しました「(d) イテレータ自体の毎回の算出コード」がそこに加わります
一般的にも今回の特殊な用途(c)を除いた3つ(a)(b)(d)は必要です
さらに>>195でいうところの仲介型イテレータはそれらの記述に加えて
「(e) 他のイテレータのメソッドとなりチェーンできるようにするための宣言」がさらに必要となります
上述(a)(b)(d)の部分の記述だけならば
お手軽にイテレータを生成できる itertools::unfold() を使えるケースだと
例えばフィボナッチ数列を返すジェネリックなイテレータは
以下のように初期値と処理クロージャを1つunfold()に与えてやればイテレータを作れます
fn fibonacci<T>() -> impl Iterator<Item=T>
where T: Clone + num::Zero + num::One + num::CheckedAdd + std::cmp::PartialEq,
{
itertools::unfold((T::one(), T::one()), |(m, n)| {
if *m == T::zero() {
// overflow
return None;
}
// shift: ret <- m <- n <- next
let next = m.checked_add(&*n).unwrap_or(T::zero());
let ret = m.clone();
*m = n.clone();
*n = next;
Some(ret)
})
}
> わざわざ決まってる数列を順番に出力するイテレータ書くのにそんな記述が必要になるのか
決まってる数列ではなく毎回算出するんですよ
記述については各々のイテレータはそれぞれ何らかの構造体にすぎないので >>176に示しましたように
「(a) イテレータとなる構造体の型宣言」「(b) その構造体の初期値定義 new()」「(c) 今回は自分と子と孫がいるためその関係記述」
があってようやく、>174に示しました「(d) イテレータ自体の毎回の算出コード」がそこに加わります
一般的にも今回の特殊な用途(c)を除いた3つ(a)(b)(d)は必要です
さらに>>195でいうところの仲介型イテレータはそれらの記述に加えて
「(e) 他のイテレータのメソッドとなりチェーンできるようにするための宣言」がさらに必要となります
上述(a)(b)(d)の部分の記述だけならば
お手軽にイテレータを生成できる itertools::unfold() を使えるケースだと
例えばフィボナッチ数列を返すジェネリックなイテレータは
以下のように初期値と処理クロージャを1つunfold()に与えてやればイテレータを作れます
fn fibonacci<T>() -> impl Iterator<Item=T>
where T: Clone + num::Zero + num::One + num::CheckedAdd + std::cmp::PartialEq,
{
itertools::unfold((T::one(), T::one()), |(m, n)| {
if *m == T::zero() {
// overflow
return None;
}
// shift: ret <- m <- n <- next
let next = m.checked_add(&*n).unwrap_or(T::zero());
let ret = m.clone();
*m = n.clone();
*n = next;
Some(ret)
})
}
197デフォルトの名無しさん
2021/12/24(金) 23:05:16.16ID:UVQKl71H198デフォルトの名無しさん
2021/12/24(金) 23:17:20.90ID:759ZBatD より良い方法に興味があるんなら、普通に既存実装を研究してみたらいいんじゃない?
例えばRubyの標準添付ライブラリにも Prime.each があるよ
ソースはここ https://github.com/ruby/prime
おれはそこまで素数のアルゴリズム自体には興味ないから考えないけど
例えばRubyの標準添付ライブラリにも Prime.each があるよ
ソースはここ https://github.com/ruby/prime
おれはそこまで素数のアルゴリズム自体には興味ないから考えないけど
199デフォルトの名無しさん
2021/12/25(土) 01:08:34.65ID:0QMGJaE9 >>197
CかC++で書いて
CかC++で書いて
200デフォルトの名無しさん
2021/12/25(土) 04:20:39.50ID:9OzOPrjS C/C++/Rustならどの言語も理解できないほどの特異な書き方や奇妙な省略もなくどれも似たようなもんだ
どれか一つで書かれていれば普通のプログラマーなら読めるだろう
それでもわからない部分があれば質問したら皆が教えてくれるぞ
どれか一つで書かれていれば普通のプログラマーなら読めるだろう
それでもわからない部分があれば質問したら皆が教えてくれるぞ
201デフォルトの名無しさん
2021/12/25(土) 06:09:26.55ID:sZ4+jXNJ202デフォルトの名無しさん
2021/12/25(土) 09:05:26.62ID:0QMGJaE9 >>200
普通のプログラマじゃなくて雑魚なんで
Rustで書かれたコードはわからないしRustの説明が欲しいわけじゃない
C/C++で書かれてれば説明無用だから全部わかるならC/C++で書いてくれない?
普通のプログラマじゃなくて雑魚なんで
Rustで書かれたコードはわからないしRustの説明が欲しいわけじゃない
C/C++で書かれてれば説明無用だから全部わかるならC/C++で書いてくれない?
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 「中国人の訪日熱は冷めた」 人気旅行先から日本外れる 14日で自粛呼びかけ1カ月 ★3 [蚤の市★]
- 高市首相の答弁書に「台湾有事答えない」と明記 存立危機発言当時 ★8 [蚤の市★]
- 「1800万円の売り上げゼロに…」中国インバウンドに特化の宿の今 ★2 [蚤の市★]
- 最新版Z級クソ映画ランキングが決定! [牛丼★]
- 公用車カーナビのNHK受信料「全額免除を」 千葉市議会、国に制度創設求める意見書可決 [少考さん★]
- 【食】「シャウエッセンは焼くべからず」暗黙のルールを破り売上高過去最高…日本ハム社員たちが「夜味」にかけた情熱 [ぐれ★]
- どこだ?強ええええバキぼんやは????
- ( ´・ω・` )どいてもらえます?
- 【埼玉】34歳無職、置き配📦を盗みまくる!その数、400点!😱 [718678614]
- 福井県民に頭おかしくされて悔しいからスレ立て
- 【MLB】打率3割と2桁ホームランを達成した日本人はイチロー、松井、大谷だけ←これ
- なあ、「石破さんにもう一回やって頂く」って選択肢って…ないか? [976717553]
