簡單記錄一下。

我把 node_modules/scaffolds/source/themes/_config.ymlpackage.json 放到 bitbucket 的 private git repository,另一台電腦裝 node.js 跟 hexo,clone repository 下來就可以了。

原本順利弄完也就好了,我就手賤的做了 npm update -g 更新 hexo,然後 generate 就爛了。後來約莫是 hexo init .npm install,然後 merge 一些改過的 theme 檔案跟 config,才總算好了。

技術 blog 沒有搜尋挺麻煩的,儘管有設 tag,但還是搜尋最方便。之前在 Octopress 用的 Tapir 不支援中文,看起來沒什麼解,只好另尋新歡(?)。找到 Swiftype 這套,除了基本搜尋功能外,Swiftype 還提供調整搜尋結果、統計分析等功能。

註冊、輸入 URL,它處理完後到 INSTALL 頁面 copy source code 到 theme 中相應 call search_form() 的地方。每個 theme 的位置不太一樣,nut 在 layout/_widget/search.ejs,landscape 在 layout/_partial/header.ejs

發現一個問題:在 overlay 的顯示方式下,搜尋結果的頁面太長,scroll bar 無法捲到最下面。想改成結果直接顯示在頁面,不用 overlay,之後參考這裡看怎麼改。

沒進,只對 A,不過這是我第一次 R1 破蛋……2013 年掛蛋,2011 年也是,其他年份沒參加。

一整個亂……= =

考慮過從最遠古的祖先直接建表,但想想覺得應該不行。就變成往回推的判斷:

  1. 若 Q 是奇數,則 impossible。
  2. Q / P = x (x 為整數) = 2 ^ n,則 ans = n
  3. Q' = Q / 2 直到 Q' < P(記錄除的次數 n),P' = P - Q',recursive 檢查 P'/Q' 是否可能出現。是則 ans = n,否則 impossible。

既然有 code 可以檢討還是檢討一下好了。

  1. 看看那精美的 scanf(),又一次 C++ format input/output 不熟。
  2. 邏輯上有方向但細節沒想清楚,像 Q 一直除 2 的時候原本沒先檢查是不是能整除,原本也沒處理處理特殊值 1。
  3. 大測資一開始沒用 long long int,然後就 segementation fault 了。

屬於 Creational pattern。

確保 class 只有一個 instance,並且給它 global 的存取點。

可以做到延後產生 instance,也就是真正使用到時才 create instance。如果用 global variable,依據不同語言及實作的特性可能在程式一開始就產生 instance。

常用來管理 shared resource。

做法

  • 將 constructor、copy constructor、destructor、assignment operator 宣告為 private 確保外面無法產生第二個 instance 及 destory instance。
  • 使用 static function 讓外界取得唯一的 instance。

C++ 實作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Singleton
{
public:
static Singleton* GetSingleton();

private:
Singleton() { /* implement */ };
~Singleton();
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
};

Singleton* Singleton::GetSingleton()
{
static Singleton* pSingleton = new Singleton();
return pSingleton;
}

外面要取得 instance 時 call Singleton::GetSingleton()。這邊直接用 C++ 的 static local variable 在 function 第一次 call 時會 initialize 之後不會再 initialize 的特性,而它的 lifetime 會持續到程式結束。

有另一種做法是 GetSingleton() 不 return pointer,而 return reference。

這個實作沒有 thread-safe,有多個 thread 會 call GetSingleton() 就 GG 了。要 thread-safe 可以用 double-checked locking。

Ref

簡單來說,我變心了。

Octopress 隨著文章數越多 rake generate 似乎有越來越慢的趨勢,稍微查一下發現雖然有 generate 加速的方法,但遇到 deploy 還是會慢,索性跳到比較快的 Hexo。

Hexo 也可以配合 Github page 使用。跟 Octopress 的不同的是 Hexo 把 post 跟 draft 分開,還不錯。

從 Octopress 轉到 Hexo 不難,先安裝好 Hexo,再將原本 _posts/ 底下的檔案搬過來便是。Hexo 不像 Octopress 將 source 開成另一個 branch 可以 push 到 repos 上,為了備份跟遠端傳輸 source 檔,我把整個 Hexo 資料夾放在 Dropbox 上。理論上電腦有裝 node.js 跟 Git 的環境就可以直接寫。

偶爾改爛 theme,放在 Dropbox 上就不知道自己改了什麼、改不回去,試驗開另一個 repos 放 source。

新增頁面

1
$ hexo new page <name>

在導覽列加新的頁面要修改 themes/<theme name>/_config.yml,在 menu 底下加,例如:

1
2
3
4
5
menu:
Home: /
Archives: /archives
Toy: /toy
About: /about

這個設定因 theme 而異,以上設定是 default theme landscape 的。

Custom Domain Name

source/ 底下增加一檔案 CNAME,內容為自訂 domain name,如 www.cjwind.idv.tw

Theme

改用 nut

修改 Deploy git repos

除了修改 _config.ymldeployrepo 的設定外,也要刪除 .deploy/,才會套用新的 repos 設定。

Ref

發現兩個問題:Tapir 不支援中文、換過 permalink 會怪怪的。

2014/4/28 updated


Octopress 預設的 search 功能是 Google search,一搜尋就會導到 Google 的頁面。不太喜歡這種方式,把 search 換成 Tapir,可以在自己站內找。

Tapir 的原理是它每 15 分鐘會掃一次網站的 RSS,再透過他們的 API 達到以 RSS 為 base 的搜尋功能。要注意的是,沒在 RSS 中的文章是不會被 search 到的。

修改方式

先到 Tapir 輸入 RSS feed 跟 mail,會得到一組 key,這裡只需要用到 public key。

Octopress Tapir plugin 下載所需檔案並放到對應資料夾。

  • source/search.html
  • source/javascripts/jquery_tapir.js
  • source/images/loading.gif

修改 _config.yml

  • 註解掉 simple_search
  • 加入 tapir_token: [your public key from Tapir]

修改 source/_includes/navigation.html,在 include custom/navigation.html 前面加入:

{% if site.tapir_token %}
{% endif %}

修改 source/atom.xml,拿掉 for post in site.posts limit: 20limit: 20,讓所有 post 都會出現在 RSS feed 。另一個可能的做法是複製 source/atom.xmlsource/atomForSearch.xmlrake generate 後將這個 XML 的 URL 丟給 Tapir 當作 search 的 base。

Ref

掛蛋啦哈哈哈哈哈哈哈哈…….Orz…..

早上八點半爬起來,弄一弄我只剩十分鐘清醒,所以一開始整個沒醒。看了 A 的題目,十幾二十分鐘後,中華電信來弄網路跟 MOD,弄完就十點了,我實在有點想跟他說 MOD 放著不用裝了,依照我們的習性大概也沒人會去開來看。網路弄完,醒了但也只剩 1.5 小時。

稍微想一下 A,只想到計算 0 跟 1 的個數可以判斷是不是 possible,但是計算次數的部分就還沒想到。後來去看 B,整個覺得我好久沒看這種東西,沒想清楚題目,自以為邊只有三種情況,寫了條件很多的 BFS,寫完 WA 到天邊去,反正掛蛋也沒有 penalty 問題…..(欸)

平常沒在練習,掛蛋也不是什麼很稀奇的事。下一場 1B 的時間對我來說太爛了(我是作息時間不太工程師的工程師),只好 1C 再戰。

把多個 .gpx 檔案接成一個檔的小工具,目前只支援從 Endomondo 抓來的 gpx 檔,不確定這是不是 gpx 的固定格式。UI 很醜我真的知道,拜託不要要求工程師的美感。

使用方式:Add 新增要合併的 gpx 檔案,Del 刪掉。Up 跟 Down 排列 gpx 檔案的順序,結果檔中的內容會以檔案列表的順序排列。

記錄一下寫這小玩具學到的東西:

  • Parse XML by C++ with Pugixml
  • Setup Qt develop environment with Qt Creator in Windows
  • Usage of release in Github
  • Deploy Qt application in Windows

這篇是看 Qt4 Container 相關網頁的筆記,包含三種 Sequential Container:QVector、QList、QLinkedList。PS:Qt 已經出到 5。(2014/4/21)

Read more »

libcurl 是處理收送網路 request、response 的 library,可用來收送 HTTP 的 request 及 response。

libcurl 收到 response 時會 call callback function,由 callback function 處理收到的資料。callback function 可自行撰寫,其 prototype 如下:

1
size_t func(void *ptr, size_t size, size_t nmemb, void *userdata)
  • ptr 指向收到的資料
  • nmemb 為收到資料的大小
  • userdata 可自己定義,我拿它當 return value。

libcurl 的 callback function 分成處理 header 跟 data,用 curl_easy_setopt() 指定處理的 callback function。如果沒有指定 callback function,預設上 data 會被印出來,header 則不處理。

Usage

1. Initialize

1
2
3
#include <curl/curl.h>

CURL* curl = curl_easy_init();

2. Set HTTP header data

設 HTTP header,如指定 Content-type:

1
2
3
struct curl_slist* headers;
memset(header, 0, sizeof(headers));
headers = curl_slist_append(headers, "Content-type: application/json");

call curl_slist_append() 會不斷加資訊到 headers 這個資料結構中。

3. Set options

1
2
3
4
5
6
7
8
9
10
curl_easy_setopt(curl, CURLOPT_POST, 1);                // 以 POST 傳送資料
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // 指定 header
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // 指定 url
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata); // 指定 data,將 postdata 當作 POST data 傳給 server

curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parseHeader); // 指定處理 HTTP header 的 callback function 為 parseHeader
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &rescode); // 指定 parseHeader 的 userdata

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, getResponse); // 指定處理 data 的 callback function 為 getResponse
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); // 指定 getResponse 的 userdata

4. 傳送 request

1
curl_easy_perform(curl);

以 blocking 的方式傳送 request。

5. clean up

1
2
curl_slist_free_all(headers);	// 清掉 headers 裡的東西
curl_easy_cleanup(curl);
Read more »