伊莉討論區

標題: 作業練習 [打印本頁]

作者: weirdococo    時間: 2019-12-22 07:30 PM     標題: 作業練習

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

用rust寫,
要寫Munchausen numbers

我嘗試著寫成這樣[attach]129922697[/attach]

然後出現這樣錯誤
[attach]129922740[/attach]
這要怎麼解? 好像是要給reference型別!
[attach]129922721[/attach]
改成這樣就可以跑了!但是不太對!還是沒有把那個 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
作者: 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
不是很明確, p 在那宣告的?

算是在||裡面宣告的吧?
大概就和c++ 語法裡面的
[=] (int p)  -> int {  /* do something */ }
一樣


題外畫,這是參考python寫的,像這樣
  1. for i in range(5000):
  2.           if i == sum(int(x) ** int(x) for x in str(i)):
  3.                     print(i)
複製代碼

補充內容 (2019-12-23 10:42 AM):
ps 我基本上沒寫過c++! 所以c++不是很熟悉!學校都教python....

補充內容 (2019-12-23 10:45 AM):
還有我的縮排可能排版得很差...不常用這種空白隨便打的語言...風格還沒定下來...

作者: 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
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問題!
作者: 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
如果你把他改成
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
不會爆炸!
不管如何,爆炸因該要執行錯誤,而不是編譯不過....
作者: 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
不過...... 不知道是不是誤會了什麼
i32 應該是 int 32吧
int32的range 不是 -2147483648 2147483647 嗎

你是試看
把範圍改成1..100
像是這樣一樣不能用!
所以我說問體不在這裡!
  1. use rayon::prelude::*;
  2. fn main() {
  3.     let answer:Vec<i32> = (1..100)
  4.         .into_par_iter()
  5.         .filter(|&p| -> bool {
  6.                 p.to_string().chars()
  7.                 .map(|c :char| -> u32 { c.to_digit(10).unwrap() })
  8.                 .map(|d :u32| -> i32 { (d as f64).powi(d as i32) as i32  })
  9.                 .sum::<i32>()
  10.                 == p
  11.         })
  12.     .collect();
  13.     println!("Munchausen numbers {:?}", answer );
  14. }
複製代碼

作者: tryit244178    時間: 2019-12-23 05:49 PM

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

stephenwei_lu大大說的是正確的,會爆炸,大爆炸!
基本上rust是範圍外,試試這個
  1. use rayon::prelude::*;
  2. fn main() {
  3.     let answer:Vec<i32> = (1..10000)
  4.         .into_par_iter()
  5.         .filter(|p: &i32| -> bool {
  6.                 p.to_string().chars()
  7.                 .map(|c :char| -> u32 { c.to_digit(10).unwrap() })
  8.                 .map(|d :u32| -> i32 { (d as f64).powi(d as i32) as i32  })
  9.                 .sum::<i32>()
  10.                 == *p
  11.         })
  12.     .collect();
  13.     println!("Munchausen numbers {:?}", answer );
  14. }
複製代碼

作者: weirdococo    時間: 2019-12-23 08:52 PM

本帖最後由 weirdococo 於 2019-12-23 08:58 PM 編輯
tryit244178 發表於 2019-12-23 05:49 PM
stephenwei_lu大大說的是正確的,會爆炸,大爆炸!
基本上rust是範圍外,試試這個 ...

原來還是要給型別....
一直不了解什麼時候可以用推定型別什麼時候不可以....
還有一個問題
假如果把它改成無限Iterator,要如何平行處理啊? 感覺不能直接加.into_par_iter()
還是不是很懂!?

一般感覺像這樣
  1. fn main() {
  2.     let answer:Vec<i32> = (1..)
  3.         .filter(|&p :&i32| -> bool {
  4.                 p.to_string().chars()
  5.                 .map(|c :char| -> u32 { c.to_digit(10).unwrap() })
  6.                 .map(|d :u32| -> i32 { (d as f64).powi(d as i32) as i32  })
  7.                 .sum::<i32>()
  8.                 == p
  9.         })
  10.         .take(2)
  11.         .collect();
  12.     println!("Munchausen numbers {:?}", answer );
  13. }
複製代碼







作者: 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, 也許還會有更好的做法
作者: weirdococo    時間: 2019-12-24 02:11 PM

本帖最後由 weirdococo 於 2019-12-24 04:52 PM 編輯
stephenwei_lu 發表於 2019-12-24 01:02 PM
我改了一下
2種做法
use rayon::prelude::*;

其實我是故意不加上 mut state的!
沒有變數在平行處理的時候就不會因為用共同記憶體的時候出錯!
所以嘗試著完全不用變數!
如果沒有sum這個函數的話,還可以用像python fold那種。
像是.fold(0, |a,b| a + b)  (ps 一般不能平行處理),
或是.reduce(0, |a,b| a + b)  (ps 一般可以平行處理)!




歡迎光臨 伊莉討論區 (http://wwww3.eyny.com/) Powered by Discuz!