查看完整版本: 作業練習
頁: [1]

weirdococo 發表於 2019-12-22 07:30 PM

作業練習

本帖最後由 weirdococo 於 2019-12-22 08:05 PM 編輯

用rust寫,
要寫Munchausen numbers

我嘗試著寫成這樣

然後出現這樣錯誤

這要怎麼解? 好像是要給reference型別!

改成這樣就可以跑了!但是不太對!還是沒有把那個 error message說的給解決!



補充內容 (2019-12-22 07:45 PM):
線上連結

補充內容 (2019-12-22 07:46 PM):
https://play.rust-lang.org/?vers ... 049c5e626676637e58a

補充內容 (2019-12-22 07:47 PM):
https://play.rust-lang.org/?vers ... 8a015ae5316e4970fc7...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>

stephenwei_lu 發表於 2019-12-23 10:23 AM

不是很明確, p 在那宣告的?

weirdococo 發表於 2019-12-23 10:42 AM

本帖最後由 weirdococo 於 2019-12-23 11:23 AM 編輯

stephenwei_lu 發表於 2019-12-23 10:23 AM static/image/common/back.gif
不是很明確, p 在那宣告的?
算是在||裡面宣告的吧?
大概就和c++ 語法裡面的
[=] (int p)  -> int {  /* do something */ }
一樣


題外畫,這是參考python寫的,像這樣
for i in range(5000):
          if i == sum(int(x) ** int(x) for x in str(i)):
                    print(i)
補充內容 (2019-12-23 10:42 AM):
ps 我基本上沒寫過c++! 所以c++不是很熟悉!學校都教python....

補充內容 (2019-12-23 10:45 AM):
還有我的縮排可能排版得很差...不常用這種空白隨便打的語言...風格還沒定下來...
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

stephenwei_lu 發表於 2019-12-23 12:01 PM

let x = 4_i32;
    let abs_difference = (x as f64).powi(x as i32) as i32 ;
    println!("{}", abs_difference );
    let y = 8_f64;
    let y1 = y.powi(y as i32);
    println!("{}", y1 );
    let y1 = y.powi(2);
    println!("{}", y1 );

// result
256
16777216
64

這一行
我覺得有點怪
(x as f64).powi(x as i32) as i32 ;
應該是overflow 了

weirdococo 發表於 2019-12-23 12:26 PM

stephenwei_lu 發表於 2019-12-23 12:01 PM static/image/common/back.gif
let x = 4_i32;
    let abs_difference = (x as f64).powi(x as i32) as i32 ;
    println!("{}", abs_d ...

(x as f64).powi(x as i32) as i32

x的範圍是1 ** 1 到 9 ** 9
也就是1 到3.87420489e8
那i32最大值為2.147483647e9
比它大了一個位數,因該不會overflow才對!
而且最主要的是!overflow應該會執行錯誤才對!不會編譯不過去!
!!

補充內容 (2019-12-23 12:38 PM):
在看了一下,在sum那裡可能會overflow! 因為1..100000000實在是太多了.....但是就算改1..1000都無法編譯....所以不太可能是overflow問題!...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div>

stephenwei_lu 發表於 2019-12-23 12:37 PM

如果你把他改成
use rayon::prelude::*;
fn power_sum(p:i32) -> i32 {
    println!("p={}",p);
    return p;
}

fn main() {
    let answer:Vec<i32> = (1..100000)
        .into_par_iter()
        .filter(|&p| -> bool { power_sum(p) == p })
        .collect();
    println!("{:?}", answer );
}
你就會發現 power_sum 的p 就是你的 1..100000
powi 這個func是做(次數)
不要過程, 說最後一次就好
10000 x10000.........10000次, 不會爆嗎?

weirdococo 發表於 2019-12-23 12:46 PM

本帖最後由 weirdococo 於 2019-12-23 01:02 PM 編輯

stephenwei_lu 發表於 2019-12-23 12:37 PM static/image/common/back.gif
如果你把他改成
use rayon::prelude::*;
fn power_sum(p:i32) -> i32 {

有點不一樣,最後一次是這樣
100000最後是
1**1 + 0**0 + 0**0 +0**0 +0**0 +0**0 = 1
不會爆炸
事實上最大才只是
9**9 + 9**9 + 9**9 + 9**9 + 9**9 + 9**9 = 2,324522934e9
不會爆炸!
不管如何,爆炸因該要執行錯誤,而不是編譯不過.......<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

stephenwei_lu 發表於 2019-12-23 03:09 PM

抱歉, code沒看好, 確實在func內拆分字元相乘後再相加
如果以100000000, 最多也是 387420489X8

stephenwei_lu 發表於 2019-12-23 04:29 PM

不過...... 不知道是不是誤會了什麼
i32 應該是 int 32吧
int32的range 不是 -2147483648 2147483647 嗎
那麼如果我的range是 "999999"
這個值得到數字應該是 2324522934
應該會爆不是嗎?



weirdococo 發表於 2019-12-23 04:48 PM

stephenwei_lu 發表於 2019-12-23 04:29 PM static/image/common/back.gif
不過...... 不知道是不是誤會了什麼
i32 應該是 int 32吧
int32的range 不是 -2147483648 2147483647 嗎


你是試看
把範圍改成1..100
像是這樣一樣不能用!
所以我說問體不在這裡!use rayon::prelude::*;
fn main() {
    let answer:Vec<i32> = (1..100)
        .into_par_iter()
        .filter(|&p| -> bool {
                p.to_string().chars()
                .map(|c :char| -> u32 { c.to_digit(10).unwrap() })
                .map(|d :u32| -> i32 { (d as f64).powi(d as i32) as i32  })
                .sum::<i32>()
                == p
        })
    .collect();
    println!("Munchausen numbers {:?}", answer );
}
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div>

tryit244178 發表於 2019-12-23 05:49 PM

本帖最後由 tryit244178 於 2019-12-23 06:12 PM 編輯

stephenwei_lu大大說的是正確的,會爆炸,大爆炸!
基本上rust是範圍外,試試這個use rayon::prelude::*;
fn main() {
    let answer:Vec<i32> = (1..10000)
        .into_par_iter()
        .filter(|p: &i32| -> bool {
                p.to_string().chars()
                .map(|c :char| -> u32 { c.to_digit(10).unwrap() })
                .map(|d :u32| -> i32 { (d as f64).powi(d as i32) as i32  })
                .sum::<i32>()
                == *p
        })
    .collect();
    println!("Munchausen numbers {:?}", answer );
}...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

weirdococo 發表於 2019-12-23 08:52 PM

本帖最後由 weirdococo 於 2019-12-23 08:58 PM 編輯

tryit244178 發表於 2019-12-23 05:49 PM static/image/common/back.gif
stephenwei_lu大大說的是正確的,會爆炸,大爆炸!
基本上rust是範圍外,試試這個 ...
原來還是要給型別....
一直不了解什麼時候可以用推定型別什麼時候不可以....
還有一個問題
假如果把它改成無限Iterator,要如何平行處理啊? 感覺不能直接加.into_par_iter()
還是不是很懂!?

一般感覺像這樣fn main() {
    let answer:Vec<i32> = (1..)
        .filter(|&p :&i32| -> bool {
                p.to_string().chars()
                .map(|c :char| -> u32 { c.to_digit(10).unwrap() })
                .map(|d :u32| -> i32 { (d as f64).powi(d as i32) as i32  })
                .sum::<i32>()
                == p
        })
        .take(2)
        .collect();
    println!("Munchausen numbers {:?}", answer );
}





...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

tryit244178 發表於 2019-12-24 09:06 AM

這…就不清楚了…我昨天才知道有這種程式語言…用google搜尋看看吧…

stephenwei_lu 發表於 2019-12-24 01:02 PM

本帖最後由 stephenwei_lu 於 2019-12-24 01:05 PM 編輯

我改了一下
2種做法
use rayon::prelude::*;
fn power_sum(p:i32) -> i64 {
    /* 第一種 改變 powi 那一行的參數
    return p.to_string().chars()
        .map(|c :char| -> u32 {c.to_digit(10).unwrap() })
        .map(|d :u32| -> i64 { (d as f64).powi(d as i32) as i64  })
        .sum::<i64>();
    */
    //第2種  自己加 ,  先變成 vec 後再拉出來做加法
    let x = p.to_string().chars()
        .map(|c :char| -> u32 {c.to_digit(10).unwrap() })
        .map(|d :u32| -> i64 { (d as f64).powi(d as i32) as i64 })
        .collect::<Vec<i64>>();
    let  mut sum1:i64 = 0;
    for a in x{
        sum1 += a;
    }
    return sum1;
   
}

fn main() {
    let answer:Vec<i32> = (1..10000000)
        .into_par_iter()
        .filter(|&p| -> bool { power_sum(p) == p.into() })
        .collect();
    println!("{:?}", answer );
}
你提供的網站,有個坑, 他會自己timeout
我一開始以為我邏輯有問題, 最後我把rust 裝在自己的機器上就可以跑了
如果你要跑到第3個數字出來, 還要再改一下就是了



補充內容 (2019-12-24 01:07 PM):
沒寫過 rust, 也許還會有更好的做法...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

weirdococo 發表於 2019-12-24 02:11 PM

本帖最後由 weirdococo 於 2019-12-24 04:52 PM 編輯

stephenwei_lu 發表於 2019-12-24 01:02 PM static/image/common/back.gif
我改了一下
2種做法
use rayon::prelude::*;

其實我是故意不加上 mut state的!
沒有變數在平行處理的時候就不會因為用共同記憶體的時候出錯!
所以嘗試著完全不用變數!
如果沒有sum這個函數的話,還可以用像python fold那種。
像是.fold(0, |a,b| a + b)  (ps 一般不能平行處理),
或是.reduce(0, |a,b| a + b)  (ps 一般可以平行處理)!...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div>
頁: [1]