Articles on this Page
- 01/03/12--21:00:_Vimで書初め
- 01/09/12--20:34:_HaskellでGUI
- 01/12/12--17:13:_勝手に添削 -...
- 01/14/12--06:33:_Lingr Radar For...
- 01/16/12--20:52:_trie_tree書いてみた。
More Channels
- Dec 4: cazurro's Formspring answers
- Nov 29: 놀이기계
- Dec 14: Situs Resmi Pemerintah Kabupaten...
- Dec 21: Christianity news stories on Newser
- Nov 29: Comments on Marriage And The...
- Nov 28: Ibiza Online ™
- Nov 28: 身延発
- Jan 25: What's it like in your funny...
- Nov 28: 点をつなぐ(別館)
- Dec 4: Slytherine Princess's Blog
- Dec 31: Daily Pornmovies and Pictures
- Nov 27: Bender Embroidered Apparel &...
- Nov 29: Comments for Media Ecologies and...
- Dec 22: CACOPHONY
- Jan 12: dog bites | Keyword Feed
- Dec 22: CalinPopescuTariceanu blog
- Dec 18: Twitter / SCWinery
- Jan 27: fuck you very much
- Nov 28: Associate Members of RDA
- Jan 25: The Marietta Times
- Nov 28: ゆっこの分離独立ブログ
- Nov 29: Twitter / ScrapDigital
- Dec 10: xx-7's Recently Played Tracks
- Jan 10: Banshees, Books, & Baseball »...
- Nov 29: Comments on: Homemade Gifts: Hot...
- Jan 27: beszeljukMac | Adás-vétel...
- Dec 9: The Americas: Decent Work, a...
- Nov 28: Komentarze do wpisu ale...
- Jan 24: 瀬戸智子の枕草子
- Dec 21: Gisbert zu Knyphausen im GHvC Shop
- Nov 25: Fazolčiin blogíís =0** -...
- Nov 25: ...
- Jan 27: TOOT最新情報
- Dec 21: Twitter / Favorites from...
- Jan 27: Julie News
- Nov 28: Stiri scurte locale din mures
- Nov 28: 竹内義晴Blog
- Jan 27: SunHerald.com: Sports
- Nov 28: Motherlode» Bullying
- Nov 29: Commentaires sur Le Monte saisi...
- Nov 28: Kommentare für Digitalbrett
- Nov 29: The Augmented Reality » thought...
- Dec 4: Robert Fortner
- Nov 28: Last 25 matches for Existor
- Dec 4: morning_breath's Xanga
- Nov 28: Comments On: This is How You...
- Nov 28: greek news
- Nov 29: Uploads by londonpianomasters
- Nov 28: belgica.blogabet.com
- Nov 29: » gente
|
|
Are you the publisher? Claim this channel |
|
Channel Description:
Latest Articles in this Channel:
- 01/09/12--20:34: HaskellでGUI (chan 1718684)
- 01/12/12--17:13: 勝手に添削 - strncpyの罠 (chan 1718684)
- 01/14/12--06:33: Lingr Radar For Linuxってのを書いた (chan 1718684)
- 01/16/12--20:52: trie_tree書いてみた。 (chan 1718684)
まず中平さんの vim-paint をインストール。
ynkdir/vim-paint - GitHubこのままだと日本語出せないのでパッチを当てる。
https://github.com/ynkdir/vim-paint
diff --git a/autoload/paint/bdf.vim b/autoload/paint/bdf.vimビットシフト関数は結構適当。最新のvimならbitwize関数が入ってるはずなので、そっちを使った方が良い。さらにunifontからbdfフォントを貰ってくる。
index 8485995..e8323b8 100644
--- a/autoload/paint/bdf.vim
+++ b/autoload/paint/bdf.vim
@@ -139,6 +139,98 @@ let s:font.hexbits = [
\ [1, 1, 1, 1],
\ ]
+let s:utf8len = [
+\ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+\ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+\ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+\ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+\ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+\ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0,
+\]
+
+function! s:dec2bin(v)
+ let v = a:v
+ if v == 0 | return 0 | endif
+ let ret = ""
+ while v > 0
+ let i = v % 2
+ let ret = i . ret
+ let v = v / 2
+ endwhile
+ return ret
+endfunction
+
+function! s:bin2dec(v)
+ let v = a:v
+ if len(v) == 0 | return 0 | endif
+ let i = 1
+ let ret = ""
+ for n in reverse(split(v, '\zs'))
+ if n == 1
+ let ret = ret + i
+ endif
+ let i = i * 2
+ endfor
+ return ret
+endfunction
+
+function! s:bitshift(a,b)
+ let a = s:dec2bin(a:a)
+ let a = repeat('0', 32-len(a)) . a
+ if a:b < 0
+ let a = (repeat('0', -a:b) . a[: a:b-1])[-32:]
+ elseif a:b > 0
+ let a = (a . repeat('0', a:b))[-32:]
+ endif
+ return s:bin2dec(a)
+endfunction
+
+function! s:bitand(a,b)
+ let a = s:dec2bin(a:a)
+ let b = s:dec2bin(a:b)
+ return s:bin2dec(tr((a + b), '21', '10'))
+endfunction
+
+function! s:byte2code(byte)
+ let p = a:byte
+ let n0 = char2nr(p[0])
+ if n0 < 0x80
+ return n0
+ endif
+ let l = s:utf8len[n0]
+ let n1 = char2nr(p[1])
+ if l > 1 && s:bitand(n1, 0xc0) == 0x80
+ if l == 2
+ return s:bitshift(s:bitand(n0, 0x1f), 6) + s:bitand(n1, 0x3f)
+ endif
+ let n2 = char2nr(p[2])
+ if s:bitand(n2, 0xc0) == 0x80
+ if l == 3
+ return s:bitshift(s:bitand(n0, 0x0f), 12) + s:bitshift(s:bitand(n1, 0x3f), 6) + s:bitand(n2, 0x3f)
+ endif
+ let n3 = char2nr(p[3])
+ if s:bitand(n3, 0xc0) == 0x80
+ if l == 4
+ return s:bitshift(s:bitand(n0, 0x07), 18) + s:bitshift(s:bitand(n1, 0x3f), 12) + s:bitshift(s:bitand(n2, 0x3f), 6) + s:bitand(n3, 0x3f)
+ endif
+ let n4 = char2nr(p[4])
+ if s:bitand(n4, 0xc0) == 0x80
+ if (l == 5)
+ return s:bitshift(s:bitand(n0, 0x03), 24) + s:bitshift(s:bitand(n1, 0x3f), 18) + s:bitshift(s:bitand(n2, 0x3f), 12) + s:bitshift(s:bitand(n3 & 0x3f), 6) + s:bitand(n4, 0x3f)
+ endif
+ let n5 = char2nr(p[5])
+ if s:bitand(n5, 0xc0) == 0x80 && l == 6
+ return s:bitshift(s:bitand(n0, 0x01), 30) + s:bitshift(s:bitand(n1, 0x3f), 24) + s:bitshift(s:bitand(n2, 0x3f), 18) + s:bitshift(s:bitand(n3, 0x3f), 12) + s:bitshift(s:bitand(n4, 0x3f), 6) + s:bitand(n5, 0x3f)
+ endif
+ endif
+ endif
+ endif
+ endif
+ return n0
+endfunction
+
"
" |hello, world
" +------------
@@ -146,7 +238,8 @@ let s:font.hexbits = [
" origin
function s:font.draw_text(canvas, text, org, color)
let [ox, oy] = a:org
- for c in map(split(a:text, '\zs'), 'char2nr(v:val)')
+ for c in map(split(a:text, '\zs'), 's:byte2code(iconv(v:val, &encoding, "utf-8"))')
+ call garbagecollect()
if !has_key(self.glyphs, c)
let c = self.default_char
endif
GNU Unifont Glyphsそしてコード
This page contains the latest release of the GNU Unifont, with glyphs for every printable code point...
http://unifoundry.com/unifont.html
scriptencoding utf-8出来上がり
let canvas = paint#canvas#new(100, 50)
let font = paint#bdf#loadfile(globpath(&rtp, 'font/unifont/unifont-5.1.20080820.bdf'))
let text = "あけまして"
call canvas.draw_text(text, [10, 20], font, [0, 0, 0])
let text = "おめでとう"
call canvas.draw_text(text, [10, 40], font, [0, 0, 0])
call canvas.save('kakizome.bmp')
ちなみに画像ファイル出力までに5分くらいかかります。![]()
WXやCocoaもあるみたいなんですが、Gtk慣れてるのもあるのでGtkで。
以前から、memcachedに対して簡単なコマンドをやり取りできるGUIクライアントを各言語でやってみようという一人プロジェクトをやっているのだけど、haskellって触った事が殆ど無かったのでやってみた。
module Main (Main.main) whereむむむー。haskell難しい。
import Text.Regex
import Graphics.UI.Gtk as Gtk
import Network.Memcache
import Network.Memcache.Protocol
main :: IO ()
main = do
server <- Network.Memcache.Protocol.connect "localhost" 11211
Gtk.initGUI
window <- Gtk.windowNew
Gtk.onDestroy window Gtk.mainQuit
Gtk.set window [ containerBorderWidth := 10, windowTitle := "memcachedclient"]
vbox <- Gtk.vBoxNew False 0
swin <- scrolledWindowNew Nothing Nothing
Gtk.scrolledWindowSetPolicy swin Gtk.PolicyAutomatic Gtk.PolicyAutomatic
Gtk.containerAdd vbox swin
tview <- textViewNew
Gtk.set tview [ containerBorderWidth := 1 ]
buf <- Gtk.textViewGetBuffer tview
Gtk.textViewSetEditable tview False
Gtk.containerAdd swin tview
entry <- Gtk.entryNew
Gtk.onEntryActivate entry $ do
end <- textBufferGetEndIter buf
t <- Gtk.get entry entryText
let tt = splitRegex (mkRegex " ") t
if (length tt == 2 && (head tt == "get" || head tt == "delete")) ||
(length tt == 3 && head tt == "set")
then do
case head tt of
"get" -> do
let
key = (tt !! 1)
r <- Network.Memcache.get server key
case r of
Nothing -> textBufferInsert buf end ((show key) ++ " not found")
Just v -> textBufferInsert buf end ((v::String) ++ "\n")
"set" -> do
let key = (tt !! 1)
let val = (tt !! 2)
r <- Network.Memcache.set server key val
case r of
True -> textBufferInsert buf end "OK\n"
False -> textBufferInsert buf end "ERROR\n"
"delete" -> do
let
key = (tt !! 1)
r <- Network.Memcache.delete server key 0
case r of
True -> textBufferInsert buf end "OK\n"
False -> textBufferInsert buf end "ERROR\n"
else
textBufferInsert buf end "Unknown command\n"
Gtk.entrySetText entry ""
Gtk.boxPackEnd vbox entry Gtk.PackNatural 0
Gtk.set window [ containerChild := vbox ]
Gtk.windowSetDefaultSize window 400 300
Gtk.widgetShowAll window
Gtk.widgetGrabFocus entry
Gtk.mainGUI
-- vim: set et ts=2:
なぜif-thenにelseが必須なのか、何故他の言語の変数というものに近い物が存在しないのか、Justってなんだよコノヤロ、gtk2hsのAPIがGTKっぽくないよ!とかいろいろ...
追記: 良く見たらstrncpyの罠でもなんでもなく、バッファがクリアされてないのが原因だった。って事であとでpullreqでも送っとくかな。
まぁソート関数自身の問題じゃないので控えめに。
strncpyは必ず \0 で埋めてくれるとは限らない。
404 Blog Not Found:algorithm - bucketsort.[ch] - 汎用かつlibcの*sortより高速な
dankogai/c-bucketsort - GitHub
http://blog.livedoor.jp/dankogai/archives/51764911.html
dankogai/c-bucketsort - GitHubstrncpy(3)のmanページにはこう書いてある。
bucketsort - bucket sort that can be used for general purpose
https://github.com/dankogai/c-bucketsort
なので...The strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy.
The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.
# ./bucketsort READMEとかするとNULストップしてないバッファで画面が賑やかになり、時にはけたたましいビープ音で心躍る。
サンプルプログラムの仕様が最終行の改行コードなしでも動く様にすべきなのかどうなのかが分からないので
diff --git a/main.c b/main.cこういうワークアラウンドでもOKなのかもしれないが(そういう点でfork/pullreqはやめた)、おそらくツールとして扱うなら改行コードがあった場合には削除...という動きが望ましいのでstrpbrk(3)やstrchr(3)と使ったり、自作strchrぽい処理を入れていくと他のsortと比較しておられる状況も少し変わったりするのかもしれませんね。確認してないけど。
index 67e4e00..48391b4 100644
--- a/main.c
+++ b/main.c
@@ -74,6 +74,7 @@ int main(int argc, char **argv)
if (!lines[lcur])
EXIT("malloc failed");
strncpy(lines[lcur], buf, slen - 1); // do not copy \n
+ lines[lcur][slen - 1] = 0;
}
size_t i;
// for (i = 0; i < lcur; i++) printf("%s\n", lines[i]);
sort(1)とはやってる事が違いすぎるのでそもそもな気もしなくない。どこを比較したんだろう...。
ちなみに全然オフトピだけど、GNU textutilsに入ってるsort(1)にはコア数によって動的にスレッドを生成してソートする処理が入ってるのでそういうの興味ある人はコード読むといいと思います。
といっても2ヶ月程前の話なんだけど。
mattn/lingr-radar-linux - GitHubujihisaさんに「ちゃんと動いた」ぽい様な事を報告してもらって、そう言えば紹介してなかったなーと思ったので。
notify messages in lingr. should be work well for linux/windows
https://github.com/mattn/lingr-radar-linux
要はオフィシャルが提供しているLingr Radar For MacのLinux版。pythonで書かれています。
Lingr Tools動作にはyoshioriさんのpyLingrとpit、gntpが必要。pyLingrはpipなんかでは入らないので手作業が必要。
http://radar.lingr.com/
yoshiori/pyLingr - GitHubリポジトリ内の
https://github.com/yoshiori/pyLingr
pylingr.pyをlingr-radar.pyと同じディレクトリに置いて動かせばOK。pitとgntpはpipなんかで入れる。
起動するとlingrのユーザとパスワードを求められるのでエディタで編集して保存、終了。参加しているルームの通知がGNTPプロトコルのGrowlに通知される。linuxだとgrowl-for-linuxで可能。
mattn/growl-for-linux @ GitHubちなみにどれもwindowsで動作するのでGrowl For Windows入れてる人やgrowl-for-linuxをwindowsでビルド出来る人はwindowsでも実現可能。
Introduction: Growl For Linux is Linux-compatible of Growl. Growl is a notification system for Mac O...
http://mattn.github.com/growl-for-linux/
よかったらどうぞ。
trieなんたらが話題になってたのでなんとなく書いてみた。
ベンチとかはやってない。
404 Blog Not Found:Algorithm - 連想配列の実装としてのハッシュはオワコン?
そのデータ構造は、君の魂を差し出すに足るものかい? 連想配列( Associative array )がコレクション( Collection )、すなわち数多のデータ構造をまとめるデータ構造としての覇...
http://blog.livedoor.jp/dankogai/archives/51765855.html
#include <stdio.h>
#include <stdlib.h>
typedef struct _trie {
char c;
unsigned int n;
struct _trie** next;
void* value;
} trie;
trie*
trie_new() {
trie* p = (trie*) malloc(sizeof(trie));
p->c = 0;
p->n = 0;
p->next = NULL;
return p;
}
void
trie_free(trie* p) {
unsigned int i;
for (i = 0; i < p->n; i++)
trie_free(p->next[i]);
if (p->n)
free(p->next);
free(p);
}
trie*
trie_put(trie* p, const char* key, const void* value) {
if (*key == 0) {
p->value = (void*) value;
return p;
}
trie* next = NULL;
int i;
for (i = 0; i < p->n; i++)
if (p->next[i]->c == *key) {
next = p;
break;
}
if (!next) {
if (!(next = trie_new())) return NULL;
trie** children = (trie**) realloc(p->next, p->n * sizeof(trie*));
if (!children) return NULL;
p->next = children;
next->c = *key;
p->next[p->n] = next;
p->n++;
}
return trie_put(next, key+1, value);
}
trie*
trie_get(trie* p, const char* key) {
if (p->c) {
if (p->c != *key)
return NULL;
if (p->c == *key && *(key+1) == 0)
return p;
key++;
}
int i;
trie* value = NULL;
for (i = 0; i < p->n; i++) {
if ((value = trie_get(p->next[i], key)))
return value;
}
return NULL;
}
void
safe_puts(const char* key, const trie* p) {
if (!p)
printf("%s not found\n", key);
else if (!p->value)
printf("%s: null\n", key);
else
printf("%s: %s\n", key, (char*) p->value);
}
int
main(int argc, char* argv[]) {
trie* p = trie_new();
trie* v;
trie_put(p, "foo", "bar");
trie_put(p, "bar", "baz");
v = trie_get(p, "baz");
safe_puts("baz", v);
v = trie_get(p, "foo");
safe_puts("foo", v);
v = trie_get(p, "bar");
safe_puts("bar", v);
trie_put(p, "うんこ", "うんこっこー");
v = trie_get(p, "うんこ");
safe_puts("うんこ", v);
v = trie_get(p, "404 blog");
safe_puts("404 blog", v);
trie_free(p);
return 0;
}
baz not found
foo: bar
bar: baz
うんこ: うんこっこー
404 blog not found