æ¨å¤ã¯ @emattsan ããã®Luaã¨IOã®è©±ããå§ã¾ãã @crashpon ãã交ãã¦ã¢ã»ã³ãã©ã«å¯ãéãã¤ã¤ãæå¾ @maccha ãPrologã«ã¤ãã¦ç±ãèªãããã®å
¨ã¦ã @torazuka ãããç±å¿ã«èããã¨ããç¨æãªå±éããªã¤ã©ã¯ãã®å±éèªä½ãã¡ã¿ã«æ¥½ããã w
— ãã¾ã®ããã¼ãã (@beakmark) 5æ 11, 2012
ãããªãããªã§ã@crashponãããããè¨èªãªã¿ã¯ãã®ç§°å·ãé æ´è´ãã¾ããwã
ãããªä¸ã§ãC++ã®template ã§åé¡ã解ããã¨ãã話ãããããï¼ ãдãï¼ ãªé¡ãããã¦ãã¾ãã¾ããã®ã§ãä¹
ã
ã«ãããã°ã©ãã³ã°è¨èª C++ã®templateãããã
C++ãã¹ã¿ã¼ã®é¢ã
ã¯ãã£ã¨ããããã¨ããã£ã¦ããã®ã§ããã¹ã¿ã¼ã®æ¹ããããè¦ã¦ãã¾ããããããã¤ãã¾ããã£ã¦ãããããã«æã£ã¦é ããã°ã¨ã
éé ãæ°ãã
æ®å¿µãªãã2å¹´ãããåã«äºå®ä¸æ´»åãåæ¢ãã¦ãã¾ãã¾ããããã©ãæ¸ãï¼orgãã¨ããäºãã«ãé¡ãåºãã¦ã¯å種è¨èªã§å®è£
ã競ãåããã³ãã·ã¢ã ã¨ãããéå ´ã¨ããããããã¾ããã
ããã«ããããæ稿ãããé¡ã®ã²ã¨ã¤ããéé ãæ°ãããã
æ稿ããå 容ã¯æ¬¡ã®ãããªãã®ã§ãã
å³.1ã®ãããªãæ ¼åç¶ã®çµè·¯ãããã¨ãã¾ãã
(1) ãã®ã¨ãPããQã¾ã§ããã®ã«ä½éãã®çµè·¯ããããæ°ãã¦ãã ããããã ãé åãã¯ããããªããQã«è¿ã¥ãæ¹åã«é²ã(å³æ¹åãä¸æ¹åã«ã ãé²ã)ã¨ãã¾ãã
(2) (1)ã¨æ¡ä»¶ã¯åãã§ãå³.2ã®ããã«çµè·¯ã®ä¸é¨ããªã(éããªã)å ´åã«ãPããQã¾ã§ããã®ã«ä½éãã®çµè·¯ããããæ°ãã¦ãã ããã
P-+-+-+ P-+-+-+ | | | | | | | | +-+-+-+ +-+-+-+ | | | | | | | +-+-+-+ +-+-+ + | | | | | | | | +-+-+-+ +-+ +-+ | | | | | | | | +-+-+-Q +-+-+-Q å³.1 å³.2çµè·¯ã®è¡¨ç¾ã®ä»æ¹ãè¨æ¶ã®ä»æ¹ã¯èªç±ã¨ãã¾ããä¸è¨ã®ãããªãã£ã©ã¯ã¿ã§ã®è¡¨ç¾ã§ãããã§ãããæåããããã°ã©ã ã§æ±ãããããã¼ã¿ã¨ãã¦æã£ã¦ãã¦ãOKã§ããå ¥åãå¤é¨ããã®å ¥åã§ãããã§ãããããã°ã©ã ä¸ã«ã³ã¼ãã£ã³ã°ããã¦ãã¦ãOKã§ãã
â»åé¡ã¯ãéç´¾æå¼ãé¢æ£æ°å¦ãæ°ãä¸ãçè«ãã(è¬è«ç¤¾ ãã«ã¼ããã¯ã¹)ã第3ç« éé ãæ°ãããããæåããã¦é ãã¾ããã
ã°ã©ãçè«ã®å ¸åçãªåé¡ã«ãªãã¨æãã¾ãããã°ã©ãçè«ã¯ã¡ããã¨å¦ãã§ããªãã®ã§ãèªåãªãã®è¨èã§è§£ãæ¹ãã¾ã解説ãã¾ãã
4è¡3æ¡ã®ãã¼ãã¨ããããã®éãã¤ãªãã¨ãã¸ãèãã¾ãã
é²ããæ¹åã¯ãå³æ¹åãä¸æ¹åã®ã©ã¡ãããªã®ã§ããããã¼ãã¸ã®çµè·¯ã¯ãä¸ã®ãã¼ãããã®çµè·¯ã®ã°ããã¨å·¦ã®ãã¼ãããã®çµè·¯ã®ã°ããã¨ãããã¾ãããã®ã¨ãä¸ã®ãã¼ãã«ãã©ãçãã¾ã§ã®çµè·¯ã®æ°ãnãå·¦ã®ãã¼ãã«ãã©ãçãã¾ã§ã®çµè·¯ãmã§ããã°ãå½è©²ãã¼ãã¸ã®çµè·¯ã®æ°ã¯n+mã«ãªãã¾ãã
ãã ããä¾å¤ããã£ã¦ã左端ã®ãã¼ãã¯å·¦å´ã«ãã¼ãããªãã®ã§ä¸ã®ãã¼ãããã®çµè·¯ã ãã«ãªãã左端ã®ãã¼ãã®çµè·¯æ°ã¯ä¸ã®ãã¼ãã®çµè·¯æ°ã¨åãã«ãªãã¾ããåæ§ã«ä¸ç«¯ã®ãã¼ãã®çµè·¯æ°ã¯å·¦ã®ãã¼ãã®çµè·¯æ°ã¨åãã«ãªãã¾ããã¾ãå§ç¹ã®ãã¼ãã®çµè·¯æ°ã¯1ï¼ãå§ç¹ããåããªããã¨ãã1éãã ãï¼ã«ãªãã¾ãã
ãããããã¹ã¦è¨ç®ãããã¦å³ã«ããããã¨æ¬¡ã®ããã«ãªã35éãã¨ããçããå¾ããã¾ãã
åæ§ã«å³2ã®ã°ããã¯æ¬¡ã®ããã«15éãã«ãªãã¾ãã
ãããããè¸ã¾ãã¦ã
ã¾ãã¯Haskellã§è§£ã
path 0 0 = 1 -- å§ç¹ï¼0è¡0æ¡ã®ä½ç½®ï¼ã®ãã¼ãã®çµè·¯æ°ã¯1 path 0 col = path 0 (col - 1) -- ä¸ç«¯ã®ãã¼ãã®çµè·¯æ°ã¯ã¯å·¦ã®ãã¼ãã®çµè·¯æ°ã¨åã path row 0 = path (row - 1) 0 -- 左端ã®ãã¼ãã®çµè·¯æ°ã¯ã¯ä¸ã®ãã¼ãã®çµè·¯æ°ã¨åã path row col = path row (col - 1) + path (row - 1) col -- ãã以å¤ã®ãã¼ãã®çµè·¯æ°ã¯å·¦ã®ãã¼ãã®çµè·¯æ°ã¨ä¸ã®ãã¼ãã®çµè·¯æ°ã®å main = print $ path 4 3 -- çµç¹ï¼4è¡3æ¡ã®ä½ç½®ï¼ã®ãã¼ãã®çµè·¯æ°
path 0 0 = 1 path 2 1 = path 2 0 -- 2è¡1æ¡ã®ä½ç½®ã®ãã¼ãã®çµè·¯æ°ã¯å·¦ã®ãã¼ãã®çµè·¯æ°ã¨åã path 2 3 = path 1 3 -- 2è¡3æ¡ã®ä½ç½®ã®ãã¼ãã®çµè·¯æ°ã¯ä¸ã®ãã¼ãã®çµè·¯æ°ã¨åã path 3 2 = path 2 2 -- 3è¡2æ¡ã®ä½ç½®ã®ãã¼ãã®çµè·¯æ°ã¯ä¸ã®ãã¼ãã®çµè·¯æ°ã¨åã path 0 col = path 0 (col - 1) path row 0 = path (row - 1) 0 path row col = path row (col - 1) + path (row - 1) col main = print $ path 4 3
ã¯ãããªãã®ã²ããããªãã解ãæ¹ããã®ã¾ã¾Haskellã®ææ³ã§æ¸ãä¸ãã ãã§çããå¾ããã¨ãã§ãã¾ããã
ãããããè¸ã¾ãã¦ã
é¢æ°åããã°ã©ãã³ã°è¨èªãC++ã®templateãã§è§£ã
ãã以ä¸è§£èª¬ã®å¿ è¦ããªãã®ã§ãããªãã³ã¼ãã§ãã
// åç¹ã§ã®çµè·¯ã®æ° template<char CHAR, template<int, int> class MAP, int ROW, int COL> struct C { static const int value = 0; }; // çµè·¯ãè¨ç®ãããã³ãã¬ã¼ã template<template<int, int> class MAP, int ROW, int COL> struct Count { static const int value = C<MAP<ROW, COL>::value, MAP, ROW, COL>::value; }; // åç¹ã§ã®çµè·¯ã®æ°: ãã£ã©ã¯ã¿ãã¨ã«ç¹æ®å template<template<int, int> class MAP, int ROW, int COL> struct C<'s', MAP, ROW, COL> { static const int value = 1; }; template<template<int, int> class MAP, int ROW, int COL> struct C<'l', MAP, ROW, COL> { static const int value = Count<MAP, ROW, COL - 1>::value; }; template<template<int, int> class MAP, int ROW, int COL> struct C<'u', MAP, ROW, COL> { static const int value = Count<MAP, ROW - 1, COL>::value; }; template<template<int, int> class MAP, int ROW, int COL> struct C<'b', MAP, ROW, COL> { static const int value = Count<MAP, ROW - 1, COL>::value + Count<MAP, ROW, COL - 1>::value; }; // å1ã®å³ãå®ç¾©ãããã³ãã¬ã¼ã template<int ROW, int COL> struct Map1 { static const char value = 'b'; }; // åºæ¬çã«ã¯å·¦ãä¸ã¨ãéãã template<int COL> struct Map1<0, COL> { static const char value = 'l'; }; // 0è¡ç®ã¯åºæ¬çã«å·¦ã ãéãã template<int ROW> struct Map1<ROW, 0> { static const char value = 'u'; }; // 0æ¡ç®ã¯åºæ¬çã«ä¸ã ãéãã template<> struct Map1<0, 0> { static const char value = 's'; }; // 0è¡0æ¡ç®ã¯èµ·ç¹ // å2ã®å³ãå®ç¾©ãããã³ãã¬ã¼ã template<int ROW, int COL> struct Map2 { static const char value = 'b'; }; // åºæ¬çã«ã¯å·¦ãä¸ã¨ãéãã template<int COL> struct Map2<0, COL> { static const char value = 'l'; }; // 0è¡ç®ã¯åºæ¬çã«å·¦ã ãéãã template<int ROW> struct Map2<ROW, 0> { static const char value = 'u'; }; // 0æ¡ç®ã¯åºæ¬çã«ä¸ã ãéãã template<> struct Map2<0, 0> { static const char value = 's'; }; // 0è¡0æ¡ç®ã¯èµ·ç¹ template<> struct Map2<2, 1> { static const char value = 'l'; }; // 2è¡1æ¡ç®ã¯å·¦ã ãéãã template<> struct Map2<2, 3> { static const char value = 'u'; }; // 2è¡3æ¡ç®ã¯ä¸ã ãéãã template<> struct Map2<3, 2> { static const char value = 'u'; }; // 3è¡2æ¡ç®ã¯ä¸ã ãéãã int anser1 = Count<Map1, 4, 3>::value; // å³1ã®4è¡3æ¡ã®ä½ç½®ã®ãã¼ãã®çµè·¯æ° int anser2 = Count<Map2, 4, 3>::value; // å³2ã®4è¡3æ¡ã®ä½ç½®ã®ãã¼ãã®çµè·¯æ°
以ä¸ã§ããããã§è§£ãã¾ãã
ããããã«ã³ã³ãã¤ã«ã
$ g++ -S answer.cpp
ãã®ã°ããanswer.sã¨ãããã¡ã¤ã«ãçæãããã®ã§ãã®å
容ãè¦ã¦ã¿ã¾ãï¼ãã¤ãéããã¿ã¼ã²ããã®ããã»ãµã¯PowerPC G4ã§ãï¼ã
$ cat answer.s .section __TEXT,__text,regular,pure_instructions .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 .machine ppc7400 .globl _anser2 .data .align 2 _anser2: .long 15 .globl _anser1 .align 2 _anser1: .long 35 .constructor .destructor .align 1 .subsections_via_symbols
ç¡äº_anser1
ã35ã_anser2
ã15ã¨ãæ£ããçããå¾ããã¾ããï¼çï¼ã
ãã¨ã¯@macchaããã«Prologã§è§£ãã¦ããããã°ä¸äºOK
â¦
â¦ãªããããªâ¦ã