C vs C++ vs Rust Part.2

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2021/12/15(水) 12:35:50.91ID:biBE4xC0
競え
※前スレ
C++ vs Rust
https://mevius.5ch.net/test/read.cgi/tech/1619219089/
2021/12/21(火) 09:42:52.55ID:oIl64W+t
クイックソートくらいは自作してみたほうがいい
最初混乱するだろうけど、ああなるほど!となった時に必ず経験値に加算される筈だ
2021/12/21(火) 10:37:29.68ID:91RXJaij
>>128
そりゃ彼はプログラミングにおいて新たな枠組みを作ったわけではないからな
2021/12/21(火) 12:47:53.03ID:ukVjEMSL
新たな枠組みって例えば何?
フレームワークのことではなさそうだけど
2021/12/21(火) 13:12:13.10ID:fLSFmYOm
例えば画像データの取り扱いでbitmapをそのまま処理していたような時代にpngやjpgなどのアルゴリズムをはじめて考え出して
実装したようなプログラマが新たな枠組みを作ることが出来る人
既存のライブラリ使って画像処理や表示のアプリを実装しているようなプログラマが枠組みを使うだけの人
2021/12/21(火) 13:13:16.14ID:91RXJaij
もちろん例としてプログラミングのフレームワークでもいいんじゃね?
例えばそのザッカーバーグの例ならば
Facebook社はプログラミングにおいて新たな枠組みとして世間にも広まるほどのReactを作った
一方でザッカーバーグ自体はReactを今から車輪の再発明すらできないしプログラミングにおいて新たな枠組みを作れないだろう
2021/12/21(火) 14:51:21.09ID:SKVIwMRv
枠組みに限らず何か新しいもの自力で作るには
その対象レイヤーのものを作れる能力は必要
それは当たり前

ザッカーバーグだって掲示板システムを実装する能力があったからFacebookを作れたわけだが
それを「車輪の再発明する能力」と呼ぶのかどうか

「新しい枠組み」と「車輪の再発明をする能力」の定義が曖昧すぎて中身がない
2021/12/21(火) 14:53:33.71ID:SKVIwMRv
結局のところ
「低レイヤーの開発をするには低レイヤーの実装能力が必要」という主張でしかない
2021/12/21(火) 15:02:25.60ID:91RXJaij
そこは定義でもめるから深入りしない
例えば例に挙げたReactは自分の観点からは低レイヤーではなく高レイヤー
結局これでいいかね?

各分野のプログラミングにおいて車輪の再発明すら出来ない人が
その分野のプログラミングにおいて新たな枠組みを作るのは無理
2021/12/21(火) 16:17:27.88ID:ukVjEMSL
車輪の再発明って何
自身で模倣できる程度には理解しているということ?
2021/12/21(火) 17:55:52.77ID:dNZ8oAHl
レイヤーは相対的なものだよ
低レイヤーで通じないなら下位レイヤーとでも言おうか

Reactのユーザーから見ればReactそのものの開発は下位レイヤー
Reactを作るために下位レイヤーのJavaScriptエンジンやレンダリングエンジンを再発明できる能力が必要か?
2021/12/21(火) 19:16:57.14ID:91RXJaij
話はシンプル
それぞれの分野で見ればよい

Reactの分野だったら
『自分でウェブフロントフレームワークを簡易なものでよいから作ったことあるか?あるいは作れるか?』
これだけの話

つまりReactの開発者たちと同じような立ち位置に立てるプログラマーなのか、
それともReactの消費者としてユーザーの立場のプログラマーなのか、の違い
2021/12/21(火) 21:33:34.81ID:FgftkvCZ
まとめると
「新しいウェブフロントフレームワークを作るには
ウェブフロントフレームワークを作る能力が必要」

そりゃそうだ
話はシンプルシンプル
2021/12/21(火) 22:16:57.85ID:B7hTDXPV
なんだよこれ遅っせーなー
意味分かんねーんだよこの挙動
俺のほうがもっとうまく作れる
2021/12/21(火) 23:02:50.37ID:BV9oeByN
消費者プログラマーは色んな仕組みをわかっていなかったり理解できなかったりする人が多いね
そうなると車輪の再発明すらできないし車輪の改良もできない
もちろん車輪に代わる新たな仕組みを作り出すこともできない
143デフォルトの名無しさん
垢版 |
2021/12/21(火) 23:19:52.13ID:aVQrTCZW
>>138
これ本気で言ってるのか
2021/12/21(火) 23:37:27.40ID:BV9oeByN
元の話はmapの実装方法がわからない、だから、もっと深刻な状況なのか
プログラミングする上での基本的なことは
車輪の再発明であろうと自分でやってみて体験していくべき
2021/12/22(水) 00:26:44.89ID:hlL8iDYx
習熟のために必ずしも車輪の再発明が必要であるわけではないでしょ
2021/12/22(水) 03:14:26.40ID:zUrn+LAM
発明する必要はないけど何もないところから自分の力だけで車輪を組み立てられるようにはなっておいた方が良い
2021/12/22(水) 04:06:02.73ID:3N0TjzPj
Cをやるとそういう力が身に付く
2021/12/22(水) 13:40:20.98ID:88lOWKJS
「フロントフレームワーク」なんて言い方するのかとググったら、まぁまぁ居たわ
2021/12/22(水) 14:48:58.75ID:cbZXpGCW
IPアドレスの正規表現を再発明してるやつがいたけど
ああいうのが"新しい枠組みを作ることも可能な生産者"だったのかw
2021/12/22(水) 15:12:06.24ID:ACMGo5I0
IPアドレスの仕組みも正規表現も別に目新しいものではないのでは?
何か特別な表現手法とかを導入する余地って残されていたか?
2021/12/22(水) 15:54:00.21ID:EC7ouo8z
正規表現とか言ってもただの文字列だからな
数式やアルゴリズムに落とし込めないもので再発明も何も手の出しようがないだろ
2021/12/22(水) 16:28:01.11ID:fS3VtBnk
使ってる言葉を自分なりに定義できないやつは普段物事を深く考えてない
知性の程度を簡単に測れる物差し
2021/12/22(水) 16:32:42.08ID:d0MJTsFe
つまり…?
2021/12/22(水) 18:46:01.74ID:+56mJT2x
>>151
えっ?
正規表現⊆アルゴリズム
じゃない?
155デフォルトの名無しさん
垢版 |
2021/12/22(水) 19:48:14.08ID:8fPxaOZD
正規表現は文字列の集合を表すだけですよ。
156デフォルトの名無しさん
垢版 |
2021/12/22(水) 20:06:24.06ID:ZbLVUWay
ある正規言語に対応する文字列やろ
2021/12/22(水) 20:08:22.67ID:NbFNi3kC
ただの検索や置換のためだけのメタ言語だよ
問題記述能力はない
2021/12/22(水) 22:30:17.60ID:kJHwXG4U
問題記述能力?
2021/12/22(水) 23:57:26.44ID:oj/5QvFT
>IPアドレスの正規表現を再発明してるやつがいたけど

再発明って具体的にどういうことやってたことを言っているんだろ
2021/12/22(水) 23:58:38.64ID:WkDs1ZLi
そのケースはアルゴリズムではないな
一般的に自分で一から作れる人はその時々に応じて最適なアルゴリズムを見つけ出すだろう
2021/12/23(木) 00:18:12.96ID:jzS6xQy/
何がアルゴリズムで何がアルゴリズムでないか
ちゃんと境界値テストできてる?
2021/12/23(木) 00:20:51.73ID:HHXdPx7l
数式はアルゴリズムなのか?
2021/12/23(木) 00:32:50.26ID:GoKXBRn5
俺がすごいと思ったらすごいというのをいかに客観的評価のように見せるか議論しているようにしか見えない
2021/12/23(木) 00:47:38.83ID:1+zdX/p3
>>163
その通り
ついでに「俺すごい」アピールをしてる

まあ議論には全くなってないがな
2021/12/23(木) 08:21:29.85ID:zbE03cOE
>>161
一般的には(決定性)チューリング機械で可能な処理のことだけどな。

なので一部の数式(無限大集合とか)は範囲外。
2021/12/23(木) 10:21:26.98ID:jJ3uH/7E
無限大を数値計算で扱うために優秀なソフトエンジニア達の手によって、例えば離散フーリエ変換や離散ウェーブレット変換などのアルゴリズムが工夫され考え出された
これが新しい枠組みを作り出すということ
2021/12/23(木) 10:33:51.13ID:uWdVPWrO
無限大の連続量を有限の数値で扱う
フーリエ変換
https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%BC%E3%83%AA%E3%82%A8%E5%A4%89%E6%8F%9B
https://ja.wikipedia.org/wiki/%E9%9B%A2%E6%95%A3%E3%83%95%E3%83%BC%E3%83%AA%E3%82%A8%E5%A4%89%E6%8F%9B
2021/12/23(木) 11:37:52.36ID:Gjq2t2pD
>>167
FTは無限大集合を扱っている訳では無いだろ。実数とか扱えないし。
2021/12/23(木) 12:01:15.99ID:l46o0/Jm
周期信号のフーリエ級数展開なら有限だけど連続信号を扱うなら無限積分の計算が必要
FTは無限積分を数値計算するため分割統治のバタフライ演算に落とし込んで更に演算量を抑えるため各種のアルゴリズムが考案されてる
2021/12/23(木) 12:32:25.74ID:GoKXBRn5
で、新しい枠組みを作り出すことが C vs C++ vs Rust にどう関わってくるの
2021/12/23(木) 12:46:22.58ID:l46o0/Jm
枠組みを作ることは凡人には無理
殆どは枠組みを使う人
ただ枠組みの仕組みを知らないと使うことも出来ない
172デフォルトの名無しさん
垢版 |
2021/12/23(木) 12:56:14.10ID:GHRrX/7/
最早スレチの話題に突っ込んで悪いけど、無限積分を回避できている気になっているのは気のせいであって、バタフライ演算とか関係ないからね(笑)
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億までの全ての素数を順に出力できるようになりました
このスレは数学が得意な方々が多いようなのでご検証よろしくお願いします
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.新素数)
 }
}
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
}
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(子)),
  }
 }
}
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使用
これらを足し算のみで実現できています
どうぞご検証よろしくお願いします
2021/12/23(木) 18:41:40.03ID:eB9sLMVm
嫌われ者Rusterのウザウザ全文貼り付け、見るのも嫌になる自己満足オナニー
2021/12/23(木) 18:47:57.52ID:y6QdIUGa
なんかやたら足し算のみで、って強調してるけど、
アルゴリズムはエラトステネスの篩だよね?
そう言ってくれたほうが理解しやすいよ

Rustはまだあんま良くわかってないのでコードは参考になるかも
でもテストケースに127が入ってるのはおかしくない?
2021/12/23(木) 18:49:15.20ID:y6QdIUGa
あ、おかしくなかった
すまん
2021/12/23(木) 19:25:25.17ID:2KeIelt0
アルゴリズムに興味がある場合はCが読みやすいということがよくわかった
2021/12/23(木) 20:59:20.34ID:QAvlUc5m
1億までの素数を全て求めるのが2.5億回の足し算だけで出来るものなのか??
メモリもエラトステネスだと1億必要だよな?
183デフォルトの名無しさん
垢版 |
2021/12/23(木) 23:06:13.63ID:MjSWMWRR
一億たって100メガにすぎませんからね。
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億など決まって開始する古典的エラトステネスのふるいでは上手くいかないのです
2021/12/24(金) 00:05:23.52ID:jmk0MHfo
キャッシュヒット率の話するならベンチマークとってくれ
2021/12/24(金) 00:12:47.34ID:1YPq+lkD
わざわざ決まってる数列を順番に出力するイテレータ書くのにそんな記述が必要になるのか
ちょっと普通のループでいいからC言語で書いてみてよ
2021/12/24(金) 00:19:39.24ID:HWkip0+R
>>185
ベンチマークをとる前に実装が必要だな
その前に新たなアルゴリズムも必要か
エラトステネスの篩は「指定された整数以下の素数を求めるアルゴリズム」だからイテレーターとは相性が悪そうだ
188デフォルトの名無しさん
垢版 |
2021/12/24(金) 19:37:12.56ID:MpuWLPBj
イテレータにすると、プログラミングの方向が変わるんですよ。
詳細を未来に先送りできるんです。
伝統ある手続き型の手法では、システムやライブラリを書く人が詳細を実装し、使う人は大まかな指示を出しましたよね。
イテレータ手法は、未来に詳細を決定する。
つまり使う人が細かいことを決める事になるんです。
そこらへんの詳しい話は、書籍クリーンアーキテクチャに載ってます。
この本に書かれてることがすべて正しいとは言いませんが、正しいことにしろ間違ってることにしろ、読んでおいて損はないです。
2021/12/24(金) 19:43:08.10ID:jmk0MHfo
イテレータ特有の話と言うより遅延評価全般の話に読めるが
2021/12/24(金) 20:57:48.40ID:4EcCA1ju
イテレータ万能説を唱えて長文するガチキチおじさんwww
yieldはgeneratorをレイトバインド
for(range)はiteratorをレイトバインド
async/awaitはfutrueをレイトバインド
詳細を未来に先送り!キリッw
191デフォルトの名無しさん
垢版 |
2021/12/24(金) 21:06:12.59ID:MpuWLPBj
>>190
さあご一緒に、キリツ!
2021/12/24(金) 21:28:57.48ID:fTLW+5qu
レイト「バインド」?
2021/12/24(金) 21:44:54.12ID:cMhJNtck
クリーンアーキテクチャを出してるから遅延評価のことじゃなく
IoCの一例としての高階関数のことを言いたいんじゃないかな?
2021/12/24(金) 22:01:56.18ID:piC+XKnR
昔は局所化して先送りにできることは素晴らしいことだと思ってた
でも最近そんなのは些末な事で、無能な働き者が気にすることだったなと考えを改めた
木を見て森を見ずと言うべきか
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は「未来に先送り」ではなく「未来を先取り」と捉えたほうがよくないでしょうか
そして遅延評価というよりも並行並列評価する形になりますね
したがって今回の話には適さないかなと思います
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)
})
}
2021/12/24(金) 23:05:16.16ID:UVQKl71H
>>185
そのためにもぜひ異なるアルゴリズムの実装を作ってくださるとベンチ比較できますね
いまのところ足し算で素数生成するイテレータの実装は以前に作った明らかに非常に遅い>>62
今回作った動作O(N log log N)でメモリ使用量O(√N / log N)となる>>174の2つしかないのです

>>187
そうなんですよ
エラトステネスのふるいは最初に上限数を指定するためそのままではイテレータと相性がよくないです
またメモリ使用量も大きくなってしまいます
そのため試行錯誤のうえ新たなアルゴリズムが生まれたのが今回の実装です
もっと良い方法を考えついた方は教えていただけるとうれしいです
2021/12/24(金) 23:17:20.90ID:759ZBatD
より良い方法に興味があるんなら、普通に既存実装を研究してみたらいいんじゃない?
例えばRubyの標準添付ライブラリにも Prime.each があるよ
ソースはここ https://github.com/ruby/prime

おれはそこまで素数のアルゴリズム自体には興味ないから考えないけど
2021/12/25(土) 01:08:34.65ID:0QMGJaE9
>>197
CかC++で書いて
2021/12/25(土) 04:20:39.50ID:9OzOPrjS
C/C++/Rustならどの言語も理解できないほどの特異な書き方や奇妙な省略もなくどれも似たようなもんだ
どれか一つで書かれていれば普通のプログラマーなら読めるだろう
それでもわからない部分があれば質問したら皆が教えてくれるぞ
201デフォルトの名無しさん
垢版 |
2021/12/25(土) 06:09:26.55ID:sZ4+jXNJ
>>195
ええその通りです。
ですから使いどころを間違っていると思うのです。
2021/12/25(土) 09:05:26.62ID:0QMGJaE9
>>200
普通のプログラマじゃなくて雑魚なんで
Rustで書かれたコードはわからないしRustの説明が欲しいわけじゃない
C/C++で書かれてれば説明無用だから全部わかるならC/C++で書いてくれない?
2021/12/25(土) 13:08:57.90ID:6OMvh/ue
Ruby の無限generator は、遅延評価する。lazy

普通に、メソッドチェーンを左から処理していくと、
無限に処理できないので、右から処理していく

素数は、6 で割って余りが、1 か5

余りが3なら、3で割り切れる。
余りが2, 4なら、2で割り切れる
2021/12/25(土) 13:31:00.64ID:Jczj7qaZ
素数に2,3が含まれるの忘れてる?
2021/12/25(土) 13:54:13.44ID:0QMGJaE9
if (25 % 6 == 1) {
//25は素数?
}
2021/12/25(土) 14:02:33.11ID:+KvRe5Is
>>205
さすがに必要条件と十分条件がわからないのはどうかと思う
2021/12/25(土) 14:14:33.50ID:0QMGJaE9
>>206
わからない
説明して
2021/12/25(土) 14:21:15.89ID:6Qf096MJ
>>194
その考え方がまさに木を見て森を見ず
209デフォルトの名無しさん
垢版 |
2021/12/25(土) 14:40:34.51ID:E7PEPPKI
>>207
6で割って余りが1か5になるのは素数であることの必要条件や
xが素数⇒x%6=1,5
2021/12/25(土) 15:29:54.15ID:0QMGJaE9
その事実を利用してまずは数を6で割って余りが1 or 5のとき
改めて素数かどうかを判定する関数に通すってことか?
rem = X % 6
if ((rem == 1 || rem == 5) && is_prime(X)) {
// Xは素数
}
else {
// Xは合成数
}
2021/12/25(土) 16:04:02.04ID:a8rAfIFO
必要十分を理解してないエンジンは無価値
212デフォルトの名無しさん
垢版 |
2021/12/25(土) 16:50:37.75ID:sZ4+jXNJ
電気モーターの時代だから。
2021/12/25(土) 17:51:05.49ID:cg2rHVf2
>>195
発信、受信、仲介、合成、創造?
コンピューターサイエンス分野を見てもRust公式を見てもそんな用語は1つもないけど
それってもしかしてあんたの個人的な思想ですか?それなら知りたくないのでウザいので黙っててもらえますか?
したがって今回のRustオジサンは気持ち悪い基地外だと思います
2021/12/25(土) 17:58:00.70ID:+KvRe5Is
>>213
気持ちはわかるけど最後の一文が個人的な気持ちになってて同じ穴の狢になってない?
2021/12/25(土) 18:19:18.17ID:IFpjnGkc
>発信、受信、仲介、合成、創造
たしかにこの用語なんなん? どっから出てきたの?
どの界隈のコンセンサスで得てる言葉なの?
2021/12/25(土) 18:20:04.09ID:IFpjnGkc
>コンサンサスで
じゃなくて、コンセンサスを
217デフォルトの名無しさん
垢版 |
2021/12/25(土) 18:26:25.36ID:E7PEPPKI
ワイもこの用語はわかんなかった
2021/12/25(土) 19:07:03.87ID:PUQlITfY
仲介なんて不動産屋でしか聞いたことないわw
2021/12/25(土) 19:14:05.00ID:9OzOPrjS
イテレーターを作ったことがない初心者プログラマーには理解が難しいと思うが
命名はともかくイテレーターがそのように分類されることは俺でもわかるぜ

>(1) 発信イテレータ … >>174で示しました素数生成、レンジ(0..n)、配列やVecに対するiter()などチェーンでは先頭に来るもの

これはRustだとimpl Iterator for XXXのみ実装のイテレーター
つまり他者のnext()は利用せずに他者に対してnext()を提供

>(2) 仲介イテレータ … map()、filter()、enumerate()などチェーンでは中間に来るもの

これはRustだとimpl Iterator for XXXおよびimpl XXX for Iteratorと両方実装のイテレーター
つまり他者のnext()を利用しつつ別の他者に対してnext()を提供

>(3) 受信イテレータ … find()、fold()、collect()などチェーンでは最後に来るもの

これはRustだとimpl XXX for Iteratorのみ実装のイテレーター
つまり他者のnext()を利用するが他者に対してnext()を提供せず

以前に議論されていた消費者プログラマー(?)だと区別を一生気付かないままかもしれぬ
2021/12/25(土) 19:17:12.81ID:Jczj7qaZ
本来の用語は何?
2021/12/25(土) 19:46:48.90ID:+KvRe5Is
>>218
デザインパターンのMediatorとかでは聞いたことあるのでは

>>220
2-4あたりをひっくるめてiterator adaptorというのはよく聞くけど細かい分類は >>195 の造語っぽい
222デフォルトの名無しさん
垢版 |
2021/12/25(土) 20:41:43.56ID:qfkDfu3c
>>219
自演バレバレやぞw
2021/12/25(土) 21:08:04.90ID:9OzOPrjS
>>220
知らん
しかしプログラマーとしてはそれらの違いは必須の知識
なんせ真逆だからな
impl Iterator for XXX
impl XXX for Iterator

>>222
わざわざ知らない役をやって同調するバカをおびき寄せてから知ってる役をしてるってか?
しねーよ
2021/12/25(土) 21:22:55.51ID:0QMGJaE9
足し算で素数を求めるアルゴリズムについて知りたいんだが誰かC/C++で書ける人いないの?
2021/12/25(土) 21:41:11.69ID:Sq1Xjjv1
独自に分類名を付けようとする試みは評価するが
チュートリアルに書いてるレベルの内容で
「初心者プログラマーには理解が難しいと思うが」とか言っちゃう初心者プログラマーはどうかと思う
2021/12/25(土) 21:53:14.53ID:Sq1Xjjv1
公式用語はsource、adapter、consumer
227デフォルトの名無しさん
垢版 |
2021/12/25(土) 22:31:39.88ID:sZ4+jXNJ
イテレータはライブラリ作者と利用者の間でループをやり取りするには便利なものです。
しかし、それ以外で使ってもパッとしない。
2021/12/25(土) 23:31:43.20ID:nV1lOrYt
>>203 >>210
素数列の生成でそんな何度も割り算しまくるような無駄はしないはず
そんなことしていたら足し算平均2.5回のより遅くなってしまう
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況