はてなキーワード: charとは
FizzBuzz続き
Cにもlambdaがあればいいのに
#include <stdio.h> #include <unistd.h> #define FALSE 0 #define TRUE !FALSE typedef struct state_t { int state; int num; int max; int outputted; } state_t; typedef struct fsm_t { state_t *(*func)(struct fsm_t *, state_t *); int divider; char *str; } fsm_t; static state_t *fizzbuzz(fsm_t *, state_t *); static state_t *end_of_line(fsm_t *, state_t *); static state_t *cond(fsm_t *, state_t *); static state_t *succ(fsm_t *, state_t *); static fsm_t fsm[] = { { fizzbuzz, 3, "Fizz" }, { fizzbuzz, 5, "Buzz" }, { end_of_line, 0, NULL }, { cond, 0, NULL }, { NULL, 0, NULL }, }; static state_t *fizzbuzz(fsm_t *fsm, state_t *cur) { if ((cur->num % fsm[cur->state].divider) == 0) { printf("%s", fsm[cur->state].str); cur->outputted = TRUE; } return succ(fsm, cur); } static state_t *end_of_line(fsm_t *fsm, state_t *cur) { if (!cur->outputted) printf("%d", cur->num); puts(""); cur->outputted = FALSE; return succ(fsm, cur); } static state_t *cond(fsm_t *fsm, state_t *cur) { if (++cur->num > cur->max) return NULL; return succ(fsm, cur); } static state_t *succ(fsm_t *fsm, state_t *cur) { if (fsm[++cur->state].func == NULL) cur->state = 0; return cur; } int main(void) { state_t state = { 0, 1, 100, FALSE }; state_t *cur = &state; while ((cur = (*fsm[cur->state].func)(fsm, cur)) != NULL) ; return 0; }
http://anond.hatelabo.jp/20081026002746
ステートマシン大好きっ子としては書かずにいられない
もう少しがんばればforも無くせるな
fsmの中身ってDRYなの?的な話もあるだろうが,こんなもの他のプログラムで自動生成すればいいんだよ!(開き直り)
#include <stdio.h> static int process(unsigned char *str, int c) { if (str != NULL) puts(str); else printf("%d\n", c); return ++c % (3 * 5); } static int iter(int c) { return process(NULL, c); } static int fizz(int c) { return process("Fizz", c); } static int buzz(int c) { return process("Buzz", c); } static int fizzbuzz(int c) { return process("FizzBuzz", c); } static int (*fsm[])(int) = { fizzbuzz, iter, iter, fizz, iter, buzz, fizz, iter, iter, fizz, buzz, iter, fizz, iter, iter }; int main(void) { int i, state; for (i = state = 1; i <= 100; i++) { state = (*fsm[state])(i); } return 0; }
Thanks. 確かにそうなんだけど、putsだと勝手に改行が出力されてしまうので一ヶ所しか使えなかった。DRY、forなし、ifなし(:?使ってるのでインチキだけど)、main以外に関数なし風味。これで完成ということにして寝ます。
int main() { int fizz_buzz(int i, int limit) { int do_fizz_buzz(int num, int divisor, const char* str, int print) { return num % divisor == 0 ? do_fizz_buzz(num / divisor, divisor, str, 1) : (printf("%s", print ? str : ""), num); } do_fizz_buzz(do_fizz_buzz(i, 3, "Fizz", 0), 5, "Buzz", 0) == i ? printf("%d\n", i) : puts(""); return i++ == limit ? 0 : fizz_buzz(i, limit); } return fizz_buzz(1, 100); }
移植性の話は厳禁でw
さっきのはあまりに汚かったのでちゃんと書いたよ!!
static int do_fizz_buzz(int num, int rem, const char* str, int print) { if (num % rem == 0) { return do_fizz_buzz(num / rem, rem, str, 1); } if (print) printf("%s", str); return num; } int fizz_buzz(int num, int rem, const char* str) { return do_fizz_buzz(num, rem, str, 0); } int main(){ int i; for(i=1; i<=100; i++){ if(fizz_buzz(fizz_buzz(i, 3, "Fizz"), 5, "Buzz") != i) printf("\n"); else printf("%d\n", i); } return 0; }
どうでしょうか?>元増田
これでおしまいだよ
(require 'cl) ; for cl-seq (defvar sangels-movies-dir nil) (defvar sangels-player "c:/Program Files/GRETECH/GomPlayer/GOM.exe") (defvar sangels-sort-by 'sangels-sort-by-rate) (defvar sangels-rate-file "~/.emacs.d/.sangels/rate") (defvar sangels-buffer "*sangels*") (defvar sangels-thumbnail "00_thumbnail.jpg") (defvar sangels-m3u "00_movies.m3u") (defface sangels-name '((t (:family "fixed" :weight bold :height 3.0))) "") (defface sangels-rate '((t (:family "fixed" :weight bold :height 1.5))) "") (defvar sangels-mode-map (let ((map (make-sparse-keymap))) (define-key map "n" 'next-line) (define-key map "p" 'previous-line) (define-key map (kbd "RET") 'sangels-select) (define-key map (kbd "SPC") 'sangels-select) (define-key map "q" 'sangels-quit) (define-key map "+" 'sangels-rate-plus) (define-key map "-" 'sangels-rate-minus) map)) (defvar sangels-mode-hook nil) (defvar sangels-highlight-overlay nil) (defvar sangels-rate-alist nil) (defconst sangels-rate-max 6) (defun sangels-insert-movies () (save-excursion (let* ((inhibit-read-only t) (files (remove-if-not (lambda (x) (and (not (member (file-name-nondirectory x) '("." ".."))) (file-directory-p x) (member sangels-thumbnail (directory-files x)))) (directory-files sangels-movies-dir t))) (ids (mapcar 'file-name-nondirectory files))) (erase-buffer) (setq ids (sangels-sort-ids ids)) (dolist (id ids) (let ((file (expand-file-name id sangels-movies-dir)) (pos (point))) (insert-image-file (expand-file-name sangels-thumbnail file)) (end-of-line) (insert (propertize (format "%-15s " id) 'face 'sangels-name)) (sangels-insert-rate id) (insert "\n") (put-text-property pos (point) 'sangels-id id)))))) (defun sangels-sort-by-name (a b) (string< a b)) (defun sangels-sort-by-rate (a b) (or (> (sangels-rate a) (sangels-rate b)) (sangels-sort-by-name a b))) (defun sangels-sort-ids (ids) (sort ids (or sangels-sort-by 'sangels-sort-by-name))) (defun sangels-insert-rate (id) (let ((rate (sangels-rate id))) (insert (propertize (concat (make-string rate ?★) (make-string (- sangels-rate-max rate) ?☆)) 'sangels-rate t 'face 'sangels-rate)))) (defun sangels-current-id () (get-text-property (point) 'sangels-id)) (defun sangels-play-movie (movie) (let ((explicit-shell-file-name "cmdproxy") (shell-file-name "cmdproxy")) (apply 'call-process-shell-command "start" nil "*tmp*" nil (mapcar (lambda (x) (concat "\"" x "\"")) (list sangels-player (unix-to-dos-filename movie)))))) (defun sangels-select () (interactive) (let ((id (sangels-current-id))) (when id (sangels-play-movie (expand-file-name sangels-m3u (expand-file-name id sangels-movies-dir)))))) (defun sangels-quit () (interactive) (kill-buffer sangels-buffer)) (defun sangels-rate (id) (or (cdr (assoc id sangels-rate-alist)) (/ sangels-rate-max 2))) (defun sangels-rate-save () (interactive) (let ((dir (file-name-directory sangels-rate-file))) (unless (file-exists-p dir) (make-directory dir t))) (with-temp-file sangels-rate-file (insert (pp-to-string sangels-rate-alist)))) (defun sangels-rate-load () (interactive) (when (file-exists-p sangels-rate-file) (with-temp-buffer (insert-file-contents sangels-rate-file) (goto-char (point-min)) (setq sangels-rate-alist (read (current-buffer)))))) (defun sangels-rate-plus (&optional n) (interactive "p") (setq n (or n 1)) (let* ((id (sangels-current-id)) (cell (assoc id sangels-rate-alist))) (unless cell (setq cell (cons id (sangels-rate id))) (setq sangels-rate-alist (cons cell sangels-rate-alist))) (setcdr cell (+ (cdr cell) n)) (save-excursion (let ((inhibit-read-only t)) (beginning-of-line) (goto-char (next-single-property-change (point) 'sangels-rate)) (delete-region (point) (next-single-property-change (point) 'sangels-rate)) (sangels-insert-rate id))) (sangels-rate-save))) (defun sangels-rate-minus (&optional n) (interactive "p") (setq n (or n -1)) (sangels-rate-plus (- n))) (defun sangels-post-command-hook () (save-excursion (move-overlay sangels-highlight-overlay (progn (move-beginning-of-line 1) (point)) (progn (move-end-of-line 1) (forward-line) (point)) (current-buffer)))) (defun sangels-mode () (interactive) (kill-all-local-variables) (use-local-map sangels-mode-map) (setq sangels-highlight-overlay (make-overlay 0 0)) (overlay-put sangels-highlight-overlay 'face 'highlight) (overlay-put sangels-highlight-overlay 'evaporate t) (make-local-variable 'post-command-hook) (add-hook 'post-command-hook 'sangels-post-command-hook nil t) (setq major-mode 'sangels-mode) (setq mode-name "Sangels") (run-mode-hooks 'sangels-mode-hook) (set-buffer-modified-p nil) (setq buffer-read-only t)) (defun sangels (&optional arg) (interactive "P") (when (or arg (not sangels-movies-dir)) (setq sangels-movies-dir (read-directory-name "movies dir: "))) (sangels-rate-load) (switch-to-buffer (get-buffer-create sangels-buffer)) (sangels-insert-movies) (sangels-mode)) (provide 'sangels)
mutexはmutual executionの略で、書籍とかには「ミューテックス」とはあまり書かない。Wikipedia(ja)くらいである。カタカナで書く場合は「ミューテック」と書くことが多い。口語では「ミューテクス」だろうがなんでもいいが「みゅーてっくつ」とか書かれると大丈夫かなと思う。charをたむけんよろしく「ちゃ〜」と読んでないか心配である。「ちゃ〜配列の終端には「なる」をせっていする」とか書いてくれそうでそれは期待。
そしてPOSIX関数の醍醐味であるpthread_createで引数に値を設定しない、呼び先で参照しない。せっかくのvoid*の使い方を覚える機会を捨てている。コンパイル時のエラーを消すためだけにvoid *でキャストしてないか心配である。
pthread_mutex_tは初期化する時にPTHREAD_MUTEX_INITIALIZERを使うかPTHREAD_RECURSIVE_MUTEX_INITIALIZER_NPを使うかPTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NPを使うかでもいいような気もするが、特に触れていない。pthread_mutex_init()の第2引数でNULLを指定するのもpthread_mutexattr_init()で初期化(デフォルト値)するのも複数環境でまったく挙動の違うアプリが出来上がるのでやめた方が自分の身のためなのだが。
排他がかかっているかどうかのチェックならpthread_mutex_trylock()もあるのだが、特に触れていない。
POSIXにはmutexの他に「読み込み中の読み込み」を許可するpthread_rwlock_tもあるのだが、特に触れていない。
プロセス内の排他であるmutexとプロセス間の排他であるセマフォの区別がついていない。これはすごい。
追記
申し訳ない。そんなに煽るようなつもりはなかった。忘れてくれ。自戒のためにこのエントリは残しておくよ。
amachangには頑張ってpthreadを極めてほしい。
(define str "Hello world") (let ((a 0)) (let1 b (with-input-from-string str (lambda () (port-fold (lambda (c b) (if (eqv? #\o c) (inc! a)) (+ 1 b)) 0 read-char))) (print a " " b)))
あるいはこう。
(use srfi-1) (define (times* e n) (map (lambda _ (e)) (iota n))) (define-macro (with-gensyms var . body) `(let ,(map (cut list <> '(gensym)) var) ,@body)) (define-macro (with-gensyms* var n . body) `(let ((,var (times* gensym ,n))) ,@body)) (define-macro (port-vfold proc seed reader) (with-gensyms (loop %proc v) (with-gensyms* pr (length seed) (with-gensyms* npr (length seed) `(let ((,%proc ,proc)) (let ,loop ((,v (,reader)) ,@(map list pr seed)) (if (eof-object? ,v) (values ,@pr) (receive ,npr (,%proc ,v ,@pr) (,loop (,reader) ,@npr))))))))) (receive (a b) (with-input-from-string "Hello world" (lambda () (port-vfold (lambda (c a b) (values (if (eqv? #\o c) (+ a 1) a) (+ 1 b))) (0 0) read-char))) (print a " " b))
文字列操作関数って高価じゃね?
getter/setterを関数で書くと、後ろに()を付けないといけないから格好悪い!!
って人にオススメ?
template<typename T>struct _property{
virtual operator T() = 0;
typedef T _t;
};
class asdf{
int foo;
public:
struct __foo : _property<int>{
asdf &parent;
operator _t(){
printf("親クラス(?)のメンバへのアクセスが面倒...");
return parent.foo;
}
__foo(asdf &p) : parent(p){}
}y;
struct : _property<char*>{
operator _t(){
printf("ここに副作用付き処理を書ける!?\n");
printf("この関数が参照を返せばgetもどきも実装できる!?\n");
return "ふひひひ!やったね!!";
}
}x;
asdf(int v) : y(*this){ foo = v * v - v - v; }
};
void p(char*s){ printf("\n増田はこちらを振り返ると、\n悲しそうな顔をしてこう言った\n「%s」\n", s); }
int main(){
asdf a(127);
//生でprintfに渡すと型推論が行われない
//それ以外の関数だったら問題ないかも
p(a.x);
printf("\n");
//どうしてもと言うならキャストすべし
printf("\n%d\n", (int)a.y);
return 0;
}
VC8で動作確認してるよ!
はっきり言って普通にgetter/setter書くよりも手間多いね!