Twitterã§ãã©ãã¼ãã¦ãã ãã£ã@rbtnnããã®ããã°ãhttp://b-rabbit-alice.blogspot.com/ããæèªãã¦ããããé¢ç½ããã®ãè¦ã¤ãã¦ãã¾ãã¾ããã
ããããã®å¤§å¥½ãï¼ç¬ï¼ã
èªåãªãã«ã©ãã¾ã§ãããããææ¦ãã¦ã¿ã¾ããã
ãã®ããã§ããããé·ã¼ãã¨ã³ããªã«ãªã£ã¦ã¾ãã
ã¡ãªã¿ã«ãããã®ã³ã¼ãã¯GitHubにも登録してありますã
1.åºæºã確èª
ã¾ãã¯ããªãªã¸ãã«ã®ã³ã¼ãã®åä½ã®ç¢ºèªãã¹ã¿ã¤ã«ã ãèªåã®å¥½ã¿ã«åããã¦ããã¾ãããå 容ã¯ä¸ç·ã§ããããããªãã¡ã¬ã³ã¹ã«ãã¦ãªã«ãã©ããã¦ã©ããªã£ãããè¦ã¦ããã¾ãã
#include <iostream> #include <string> #include <boost/format.hpp> void print(double a, double b, double c) { const double m = (a - b) / c; const double n = a - b / c; std::cout << (boost::format("(%1% - %2%) / %3% = %4%") % a % b % c % m) << std::endl; std::cout << (boost::format(" %1% - %2% / %3% = %4%! = %5%") % a % b % c % m % n) << std::endl; std::cout << std::endl; } double factorial(double n) { return (n > 0) ? (n * factorial(n - 1)) : 1; } int main(int, char* []) { for(double a = 1; a < 1000; ++a) { for(double b = 1; b < 1000; ++b) { for(double c = 2; c < 100; ++c) { if((a > b) && ((a - (b / c)) == factorial((a - b) / c))) { print(a, b, c); } } } } return 0; }
å®è¡çµæãç¡äºおなじ結果ãå¾ããã¾ããã
(25 - 5) / 5 = 4 25 - 5 / 5 = 4! = 24 (30 - 18) / 3 = 4 30 - 18 / 3 = 4! = 24 (40 - 32) / 2 = 4 40 - 32 / 2 = 4! = 24 (138 - 108) / 6 = 5 138 - 108 / 6 = 5! = 120 (230 - 220) / 2 = 5 230 - 220 / 2 = 5! = 120 (728 - 416) / 52 = 6 728 - 416 / 52 = 6! = 720 (731 - 473) / 43 = 6 731 - 473 / 43 = 6! = 720 (735 - 525) / 35 = 6 735 - 525 / 35 = 6! = 720 (748 - 616) / 22 = 6 748 - 616 / 22 = 6! = 720 (756 - 648) / 18 = 6 756 - 648 / 18 = 6! = 720 (765 - 675) / 15 = 6 765 - 675 / 15 = 6! = 720 (816 - 768) / 8 = 6 816 - 768 / 8 = 6! = 720 (833 - 791) / 7 = 6 833 - 791 / 7 = 6! = 720 (952 - 928) / 4 = 6 952 - 928 / 4 = 6! = 720
å®è¡æéãè¨æ¸¬ãã¦ã¿ã¾ããããã¼ãã¦ã§ã¢ã¯ãã¤ãéãPowerPCã®MacãiBook G4 1.33GHzãOSã¯Mac OS X 10.5.8ãã³ã³ãã¤ã«ã¯GCC 4.0.1ããªãã·ã§ã³ã¯ -ansi -Wall
ã§æé©åã¯æå®ãã¦ãã¾ãããåä½ã¯ç§ã§timeã³ãã³ãã§è¨æ¸¬ãã¦ãã¾ããã³ã³ã½ã¼ã«åºåã¯/dev/nullã«æ¨ã¦ã¦ãã¾ãã
1åç® | 2åç® | 3åç® | å¹³å | é«éå | |
---|---|---|---|---|---|
1 | 40.255 | 40.254 | 40.242 | 40.250 | 1 |
ãé«éåãã¯ã³ã³ãåºæºãªã®ã§ã1ãã¨ãã¾ãã
2.ã¡ã¢å(memoization)
éä¹ã®å¹çåã¨ããã°ãå®çªã®ã¡ã¢å(memoization)ã
factorial
é¢æ°ãã¯ã©ã¹ã«ãã¦äºåã«è¨ç®ããçµæã¯ä¿åãã¦åå©ç¨ããããã«ãã¾ãã
ã¤ãã§ã«ãæµ®åå°æ°ç¹æ¼ç®ããªãããå²ãåããå ´åã«ã ãå¼ãæãç«ã¤ãã©ãããæ¤è¨¼ããããã«ãã¦ã¿ã¾ããã
ããã²ã¨ã¤ã¤ãã§ã«ããã©ã¡ã¼ã¿ãã³ãã³ãã©ã¤ã³ããæå®ã§ããããã«ãã¦ãã¾ãã
#include <iostream> #include <string> #include <vector> #include <boost/format.hpp> #include <boost/lexical_cast.hpp> class Factorial { public: Factorial() : factorial_() {} int operator [] (int n) const { if(factorial_.size() <= n) { factorial_.push_back((n > 0) ? (n * (*this)[n - 1]) : 1); } return factorial_[n]; } private: mutable std::vector<int> factorial_; }; bool isDivisible (int dividend, int divisor) { return (dividend % divisor) == 0; } void print(int a, int b, int c) { const int m = (a - b) / c; const int n = a - b / c; std::cout << (boost::format("(%1% - %2%) / %3% = %4%") % a % b % c % m) << std::endl; std::cout << (boost::format(" %1% - %2% / %3% = %4%! = %5%") % a % b % c % m % n) << std::endl; std::cout << std::endl; } int main(int argc, char* argv[]) { if(argc != 2) { std::cerr << "usage: " << argv[0] << " <count>\n"; return 0; } const int max = boost::lexical_cast<int>(argv[1]); Factorial factorial; for(int a = 1; a < max; ++a) { for(int b = 1; b < max; ++b) { for(int c = 2; c < max; ++c) { if((a > b) && isDivisible (b, c) && isDivisible (a - b, c) && ((a - b / c) == factorial[(a - b) / c])) { print(a, b, c); } } } } return 0; }
å®è¡çµæã¯çç¥â¦ã¨æã£ããã§ãããã²ã¨ã¤æ°ãã解ãè¦ã¤ãã¦ãã¾ãã¾ããããªãªã¸ãã«ã§ã¯c
ã®æ¢ç´¢ç¯å²ã1ã100ã ã£ãã®ã§ããããã®ç¯å²ãåºãã¦ã¿ããc
ã100ãã大ããå ´åã®è§£ãããã®ãçºè¦ãã¦ãã¾ãã¾ããã
(721 - 103) / 103 = 6 721 - 103 / 103 = 6! = 720
1åç® | 2åç® | 3åç® | å¹³å | é«éå | |
---|---|---|---|---|---|
2 | 34.817 | 34.801 | 34.803 | 34.807 | 1.15 |
ä¸ã«æ¸ããéãc
ã®æ¢ç´¢ç¯å²ãåºããå½±é¿ããããã¾ãæ©ããªã£ã¦ãªãã§ãã
3.æ¢ç´¢ããç¯å²ãçµãã
ãã£ã±ãæ¢ç´¢ããç¯å²ãåºéããã®ãããã¯ã«ãªã£ã¦ãããããªã®ã§ããããçµãè¾¼ããã¨ãèãã¾ãã
ã¾ããa
ãb
ãc
ã¯ããããæ£ã®æ´æ°ã§ã(a - b) / c
ã®çµæãæ£ã®æ´æ°ã¨ããã¨b < a
ã§ãªãã¨ãªãã¾ããããã§ã«ãµããåãã®æ¡ä»¶æã®ä¸ã«ãã®å¼ãããã¾ãããã«ã¼ãèªä½ããåãé¤ããã¨ãèãã¾ããã¾ãã(a - b) / c
ãæ£ã®æ´æ°ã¨ãããã¨ã¯ãååããåæ¯ãå°ãããªãã¨ãããªãã®ã§c < a - b
ã®ã¯ãã§ãã
ããããå ã«æ¸ãç´ããã®ã次ã®ã³ã¼ãã
#include <iostream> #include <string> #include <vector> #include <boost/format.hpp> #include <boost/lexical_cast.hpp> class Factorial { public: Factorial() : factorial_() {} int operator [] (int n) const { if(factorial_.size() <= n) { factorial_.push_back((n > 0) ? (n * (*this)[n - 1]) : 1); } return factorial_[n]; } private: mutable std::vector<int> factorial_; }; bool isDivisible (int dividend, int divisor) { return (dividend % divisor) == 0; } void print(int a, int b, int c) { const int m = (a - b) / c; const int n = a - b / c; std::cout << (boost::format("(%1% - %2%) / %3% = %4%") % a % b % c % m) << std::endl; std::cout << (boost::format(" %1% - %2% / %3% = %4%! = %5%") % a % b % c % m % n) << std::endl; std::cout << std::endl; } int main(int argc, char* argv[]) { if(argc != 2) { std::cerr << "usage: " << argv[0] << " <count>\n"; return 0; } const int max = boost::lexical_cast<int>(argv[1]); Factorial factorial; for(int a = 1; a < max; ++a) { for(int b = 1; b < a; ++b) { const int c_max = a - b; for(int c = 2; c < c_max; ++c) { if(isDivisible (b, c) && isDivisible (a - b, c) && ((a - b / c) == factorial[(a - b) / c])) { print(a, b, c); } } } } return 0; }
1åç® | 2åç® | 3åç® | å¹³å | é«éå | |
---|---|---|---|---|---|
3 | 8.570 | 8.661 | 8.667 | 8.633 | 4.66 |
ããããæ©ããªã£ã¦ãã¾ããã
4.ãã£ã¨çµããªããï¼
c
ã®ç¯å²ã§ãããa - (b / c)
ãæ£ã®æ´æ°ã«ãªããã¨ããã¨c < b
ã§ãããã¯ãã§ããã¨ãããã¨ã¯a - b
ã¨b
ã®å°ããæ¹ãããc
ã¯å°ãããªãã¯ãã
ã¨ããããã§æ¸ãæããã®ã以ä¸ã®ã³ã¼ããå¤æ´ãå°ãªãã®ã§é¨åã ãã
ãããã
const int c_max = a - b; for(int c = 2; c < c_max; ++c)
ããå¤æ´ãæ¡ä»¶å¼ã®æ¼ç®åã<=
ã«ãªã£ã¦ãããã¨ã«æ³¨æã
const int c_max = std::min(a - b, b); for(int c = 2; c <= c_max; ++c)
ã¾ããmin
é¢æ°ãã³ãã¬ã¼ãã使ãããããããã¡ã¤ã«ã追å ã§èªã¿è¾¼ã¿ã
#include <algorithm>
1åç® | 2åç® | 3åç® | å¹³å | é«éå | |
---|---|---|---|---|---|
4 | 4.502 | 4.518 | 4.545 | 4.188 | 9.61 |
ã¾ãã¾ããæ©ããªã£ã¦ãã¾ããã
5.æ¢ç´¢æ¹æ³ãè¦ç´ãã¦ã¿ã
ã¨ã¯ãããããã¾ã§ã®ããæ¹ã§ã¯ä¸éã«ã¼ããªã®ã¯ããããªãã®ã§ãããããå®æ°åã§ããæ©ããªãã¾ãããæ±ãæ°ã大ãããªãã«ã¤ãæã«è² ããªããªãã®ã¯ãããã¾ããã
æ ¹æ¬çã«æ¢ç´¢æ¹æ³ãå¤ããå¿
è¦ãããããã§ãã
a - b / c = n!
ã¨ããå¼ãè¦ãã¨ããç®ã«ã¤ãã®ã¯n
ã®å¤ã®å°ãããn!
ã¯æ¥æ¿ã«å¤ã大ãããªãã®ã§ãn
èªä½ã¯ããã»ã©å¤§ãããªãã¾ããã1000ã¾ã§æ¢ç´¢ãã¦ããããã6ã©ã¾ãããªãã°ã¨ãããã¨ã§ãn
ãã«ã¼ãã®åºæºã«ããã¦ã¿ã¾ãã
ä¸çªå¤å´ãa
ã¯ä»»æã®æ£ã®æ´æ°ã¨ãã¾ãã
a - b / c = n!
ã§ããããa = n! + b / c
ã§ãb / c
ãæ£ã®æ´æ°ã§ããããa > n!
ãæãç«ã¡ã¾ããa > n!
ã¨ãªãn
ã®ãã¡æ大ã®ãã®ãnmax
ã¨ããã°ã1â¦n
â¦nmax
ã§ãã
ã¾ãa - b / c = n!
ãããb / c = a - n!
ã«ãªãã¾ãã
c
ã1ã®ã¨ãã®b
ã®å¤ãb1
ã¨ããã¨ãb / c = b1 / 1 = b1 = a - n!
ã¨ãªãã¾ããå®éã«ã¯c
ã¯æ£ã®æ´æ°ãªã®ã§b
ã¯b1
ã®åæ°ãã¤ã¾ãa - n!
ã®åæ°ã«ãªãã¾ãã
ããã«(a - b) / c = n
ã§ãn
ã¯æ£ã®æ´æ°ã§ãããã(a - b) / c
ãåæ¯ããååã大ãããªããã°ãªãã¾ãããããã«c < a - b
ã§ãã
çµæã¨ãã¦ã
a
ã®ã«ã¼ã
n
ã®ã«ã¼ã
b
ã®ï¼b1
ã®åæ°ã®ï¼ã«ã¼ã
ã¨ãªãã¾ããå å´ã®ãµãã¤ã®ã«ã¼ããããªãå°ãããªãã¯ããªã®ã§ãå¹çåãæå¾ ã§ãã¾ãã
å®è£ ã
#include <iostream> #include <string> #include <vector> #include <algorithm> #include <boost/format.hpp> #include <boost/lexical_cast.hpp> class Factorial { public: Factorial() : factorial_() {} int operator [] (int n) const { if(factorial_.size() <= n) { factorial_.push_back((n > 0) ? (n * (*this)[n - 1]) : 1); } return factorial_[n]; } int getMaxLessOrEqual(int a) const { int result = 0; while((*this)[result] < a) { ++result; } return --result; } private: mutable std::vector<int> factorial_; }; bool isDivisible (int dividend, int divisor) { return (dividend % divisor) == 0; } void print(int a, int b, int c) { const int m = (a - b) / c; const int n = a - b / c; std::cout << (boost::format("(%1% - %2%) / %3% = %4%") % a % b % c % m) << std::endl; std::cout << (boost::format(" %1% - %2% / %3% = %4%! = %5%") % a % b % c % m % n) << std::endl; std::cout << std::endl; } int main(int argc, char* argv[]) { if(argc != 2) { std::cerr << "usage: " << argv[0] << " <count>\n"; return 0; } const int max = boost::lexical_cast<int>(argv[1]); Factorial factorial; for(int a = 20; a < max; ++a) { int n_max = factorial.getMaxLessOrEqual(a); for(int n = 1; n <= n_max; ++n) { int b1 = a - factorial[n]; for(int c = 2; (b1 * c) < a; ++c) { const int b = b1 * c; if(isDivisible(a - b, c) && (((a - b) / c) == n)) { print(a, b, c); } } } } return 0; }
1åç® | 2åç® | 3åç® | å¹³å | é«éå | |
---|---|---|---|---|---|
5 | 0.022 | 0.022 | 0.022 | 0.022 | 1830 |
ã¿ãã¨ã«é«éåã§ãã¾ããã
6.éè¨
1åç® | 2åç® | 3åç® | å¹³å | é«éå | |
---|---|---|---|---|---|
1 | 40.255 | 40.254 | 40.242 | 40.250 | 1 |
2 | 34.817 | 34.801 | 34.803 | 34.807 | 1.15 |
3 | 8.570 | 8.661 | 8.667 | 8.633 | 4.66 |
4 | 4.502 | 4.518 | 4.545 | 4.188 | 9.61 |
5 | 0.022 | 0.022 | 0.022 | 0.022 | 1830 |
ä¸æºãããã¨ããã°ãæ°å¦çã«è§£ãã¦ã¿ããã£ãã¨ããã¨ããã
æ¼ç®éãè¦ç©ãã£ã¦ããã«ãã£ã¦ã³ã¼ããæ¹åãã¦ããã¨ããã®ã¯ãæ°å¤è¨ç®ã®èãããããã°æ£æ»æ³ã ã¨æããã§ãããã§ããã°è¦åæ§ã¨ãè¦ã¤ãã¦ã¿ãããªã¼ãã¨ã
ãã¾ã¯ãããã¾ã§é ãåãã¦ã¾ããã§ããã¯ãã
7.ãã¾ãï¼C++ã§ã§ãããªãRubyã§ãã§ããããâ¦ï¼
ããã¾ã§é«éã«ã§ãããªãã¤ã³ã¿ããªã¿ã§ãå åå®ç¨ã«ãªããããã¨ãããã¨ã§Rubyã«ç¿»è¨³ãç´è¨³ãªã®ã§Rubyã£ã½ããªãããããã¾ããã
class Factorial def initialize @factorial = [] end def get(n) @factorial << ((n > 0) ? (n * get(n - 1)) : 1) if @factorial.size() <= n return @factorial[n] end def lower_bound(a) result = 0 while get(result) < a result += 1 end result - 1 end end def is_divisible(dividend, divisor) ((dividend / divisor) * divisor) == dividend end def print_abc(a, b, c) m = (a - b) / c n = a - b / c puts "(#{a} - #{b}) / #{c} = #{m}" puts " #{a} - #{b} / #{c} = #{m}! = #{n}" puts end Max = ARGV.shift.to_i factorial = Factorial.new (1...Max).each do |a| m = factorial.lower_bound a (1..m).each do |n| b1 = a - factorial.get(n) c = 2 while (b1 * c) < a b = b1 * c if is_divisible(a - b, c) && (((a - b) / c) == n) print_abc(a, b, c) end c += 1 end end end
å®è¡çµæã¯çç¥ã