Re: [問卦] 不用函數庫和亂數 寫程式求pi值的方法?

看板Gossiping作者 (很菜很魯 就是魯菜嗎?)時間5年前 (2019/04/19 17:21), 5年前編輯推噓7(701)
留言8則, 8人參與, 5年前最新討論串4/4 (看更多)
每次看到大神出來回文,就是不一樣。 小弟只是做一點補充,關於 Brainf*ck 程式語言的部分(看完腦袋都糊成一塊) 這有什麼用途呢? 用途很大,可以拯救一整個物種。 我們都知道皮卡丘在惡劣的工作環境,有事沒事都要聽從訓練家出去戰鬥, 三不五時還會被打得片體鱗傷, 為了拯救皮卡丘,除了建立收容之家,收容眾多的皮卡丘之外, 也許有一個更好的方式,就是幫他們轉職,脫離險惡的工作環境及僱主。 那要轉職什麼好呢? 考慮現在的就業市場,可以轉職成高薪的程式設計師。 我們知道皮卡丘(pikachu),只會發出三個聲音 pi ka chu, 所以我們依照皮卡丘的語言特性,設計一個專屬皮卡丘使用的程式語言。[1] 這個程式語言,可讓皮卡丘專屬使用,且容易使用。 Brainfuck Pikalang --------- --------- > pipi < pichu + pi - ka . pikachu , pikapi [ pika ] chu 所以 Hello, world! 的程式碼,使用皮卡丘程式語言,就可以寫成 pi pi pi pi pi pi pi pi pi pi pika pipi pi pi pi pi pi pi pi pipi pi pi pi pi pi pi pi pi pi pi pipi pi pi pi pipi pi pichu pichu pichu pichu ka chu pipi pi pi pikachu pipi pi pikachu pi pi pi pi pi pi pi pikachu pikachu pi pi pi pikachu pipi pi pi pikachu pichu pichu pi pi pi pi pi pi pi pi pi pi pi pi pi pi pi pikachu pipi pikachu pi pi pi pikachu ka ka ka ka ka ka pikachu ka ka ka ka ka ka ka ka pikachu pipi pi pikachu pipi pikachu 這樣子,皮卡丘們就可以順利轉職,是不是很棒呢? [1] https://esolangs.org/wiki/pikalang 當然皮卡丘程式語言,不是只有一種,也有其他設計的方式, 像是 http://trove42.com/pikachu-syntax-rules/ 大家一起來幫助皮卡丘~ ※ 引述《jserv (松鼠)》之銘言: : ※ 引述《fragmentwing (片翼碎夢)》之銘言: : : 小弟程式設計新手 : : 看到後面的講義習題要算圓周率 : : 如果不用亂數,也不用函數庫的話 : : 我自己用了一個在寫之前就覺得很浪費電腦能力的方法 : : 在電腦能力處理極限,還沒法精確到小數點後第二位呢 : : 鄉民會怎麼用程式求圓周率呢? : 這裡提供一種途徑,只用到 C 語言標準函式庫裡頭的以下函式: : * fopen / fclose : * getc / putc : 既然上述說要「浪費電腦能力」,那我們不妨試試這個策略: : a. 實作符合 Turing completeness (圖靈完備) 的 Brainfuck 程式語言 [1] : 執行環境; : b. 撰寫 Brainfuck 程式,使其得以計算圓周率,並用十進位浮點數輸出; : 可將 Brainfuck 的執行環境設想為一台機器,擁有一個讀寫頭及無限長的紙帶, : 機器會依下列指令進行操作: : > : 使讀寫頭在紙帶上前進一格 : < : 使讀寫頭在紙帶上後退一格 : + : 對目前讀寫頭下的值,進行遞增 1 的運算 : - : 對目前讀寫頭下的值,進行遞減 1 的運算 : . : 將目前讀寫頭下的值,以對應的字母輸出 : , : 將目前讀寫頭下的字母讀入並轉為數字後寫回 : [ : 比較目前的值,若不為 0 即前進,若為 0 就略過指令,直到遇上匹配的 ] : ] : 比較目前的值,若不為 0,指令要跳回上個出現 [ 的位置 : 不難發現,作為一個「知易行難」的程式語言,Brainfuck 僅有 8 個指令,其中 : 2 個是 I/O 動作。作為 Turing machine 的實踐,Brainfuck 對記憶體單元作直接 : 存取,對應到 C 語言的概念來說,如果 char *p 指向記憶體區塊的話,Brainfuck : 語言的 8 個指令可對照為以下 C 等價敘述: : Brainfuck C : --------- --------- : > ++p; : < --p; : + ++*p; : - --*p; : . putchar(*p); : , *p = getchar(); : [ while (*p) { : ] } : 也就是說,下方的 Brainfuck 程式碼: : +++++[-] : 對應到 C 語言程式碼為: : *p = +5; : while (*p != 0) { : *p--; : } : 既然有了指令對照表,我們即可著手建構小型的 Brainfuck 直譯器: (檔名為 bf.c) : #include <stdio.h> : #include <stdlib.h> : static int p[64 * 1024], d[1024 * 1024], r, t, e; : int main(int c, char *v[]) { : if (c < 2) exit(1); : for (FILE *f = fopen(v[1], "r"); f && (c = getc(f)) != EOF; p[r++] = c); : for (r = 0; (c = p[r]); r++) { : if (c == '>') t++; : if (c == '<') t--; : if (c == '+') d[t]++; : if (c == '-') d[t]--; : if (c == '.') putc(d[t], stdout); : for (e = 0; c == '[' && !d[t]; r++) { : if (p[r] == '[') e++; : if ((p[r] == ']') && (e-- == 1)) break; : } : for (; c == ']' && d[t]; r--) { : if (p[r] == ']') e++; : if ((p[r] == '[') && (e-- == 1)) break; : } : } : } : 回到一開始提到的 Turing completeness,Brainfuck 與其說是程式語言,不如說是 : 一台理想機器的描述:機器具有無限的儲存 (storage,也就是無限長的紙帶)、運算 : (arithmetic,如遞增和遞減)、條件判斷 ([ ] 涉及目前值是否為 0 的判斷) 以及 : 重複 (repetition,這也是 [ ] 的行為),Brainfuck 這台機器具備上述四項特徵, : 是 Turing completeness。依據 Alan Turing 的觀點,這樣的一台機器,即可模擬 : 人類所能進行的任何計算過程,自然就包含圓周率的計算。 : Felix Nawothnig 撰寫出可依據給定位數要求,計算並輸出十進位表示法的 Brainfuck : 程式 [2],我略作調整,如下: (檔名為 pi.b) : > +++++ +++++ +++++ +++++ +++++ (25 digits) : [<+>>>>>>>>++++++++++<<<<<<<-]>+++++[<+++++++++>-]+>>>>>>+[<<+++[>>[-<]<[>]<-]> : >[>+>]<[<]>]>[[->>>>+<<<<]>>>+++>-]<[<<<<]<<<<<<<<+[->>>>>>>>>>>>[<+[->>>>+<<<< : ]>>>>>]<<<<[>>>>>[<<<<+>>>>-]<<<<<-[<<++++++++++>>-]>>>[<<[<+<<+>>>-]<[>+<-]<++ : <<+>>>>>>-]<<[-]<<-<[->>+<-[>>>]>[[<+>-]>+>>]<<<<<]>[-]>+<<<-[>>+<<-]<]<<<<+>>> : -]<<<<+<+>>[-[-[-[-[-[-[-[-[-<->[-<+<->>]]]]]]]]]]<[+++++[<<<++++++++<++++++++> : >[>>.<<-]>[-]>[-]>>>[>>[<<<<<<<<+>>>>>>>>-]<<-]]>>[-]<<<[-]<<<<<<<<]++++++++++. : 乍看鬼畫符的程式,注意到最後一個字元是 . (將目前讀寫頭下的值,以對應的字母輸出) : 編譯 Brainfuck 直譯器並載入圓周率計算程式: : $ gcc -o bf bf.c : $ ./bf pi.b : 在我的電腦 (AMD Ryzen Threadripper 2990WX 32-Core Processor, AMD 重返榮耀!) 搭配 : Ubuntu Linux 18.04 LTS,執行時間約為 0.3 秒,ELF 執行檔約佔 6KB 空間。 : 參考執行輸出如下: : 3.141592653589793238462643 : 若要提高圓周率計算的有效位數,那麼修改 pi.b 的第一行,把 + 指令的數量增加即可。 : 用雙手駕馭電腦的滋味,真是美妙 :-) : [1] brainf*ck: https://esolangs.org/wiki/brainfuck : [2] https://copy.sh/brainfuck/prog/yapi.b -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 42.73.73.252 ※ 文章網址: https://www.ptt.cc/bbs/Gossiping/M.1555665713.A.AF7.html ※ 編輯: kcheart (42.73.73.252), 04/19/2019 17:23:05

04/19 17:23, 5年前 , 1F
程式執行下去可以放電嗎
04/19 17:23, 1F

04/19 17:27, 5年前 , 2F
原po已經很好笑了,還能想出應用真的不簡單XD
04/19 17:27, 2F

04/19 17:35, 5年前 , 3F
................................
04/19 17:35, 3F

04/19 17:40, 5年前 , 4F
傻眼
04/19 17:40, 4F

04/19 19:02, 5年前 , 5F
幫推
04/19 19:02, 5F

04/19 20:20, 5年前 , 6F
喔耶
04/19 20:20, 6F

04/20 09:23, 5年前 , 7F
感謝補充 :-)
04/20 09:23, 7F
感謝大神來加持 ※ 編輯: kcheart (114.137.196.68), 04/21/2019 12:05:07

04/21 19:23, 5年前 , 8F
笑死
04/21 19:23, 8F
文章代碼(AID): #1SkPCnht (Gossiping)
討論串 (同標題文章)
文章代碼(AID): #1SkPCnht (Gossiping)