ããã¤ãã»ãã¢ã¼ãã®è§£ãruby 60è¡ã§ã³ã¼ãã£ã³ã°
å¹´æ«ã§ãããªãããããªããã¨ãããã«ãããããããã¹ã©ãã·ã¥ããããã¼ã¼ã£ã¨è¦ã¦ãããé¢ç½ãããªè©±ãè¦ã¤ãã¾ããã
æ¬å®¶/.ã®ttsiodæ°ã¯ããã®ããºã«ã®è§£ãPythonã§60è¡ã®ã³ã¼ãã§æ¸ããããã ãã100Ã100ãã¹ã®ãã¼ãã§ã1ç§è¶³ããã§è§£ãåºãããã¨ã®ãã¨
「ナイト・ツアー」の解をPython 60行でコーディング | スラッシュドット・ジャパン
ãã¤ãã»ãã¢ã¼ã£ã¦ã®ã¯ãé¨å£«ã®å·¡æ´ã¨ãå¼ã°ããããã§ã¹ãã¢ãã¼ãã«ããããºã«ã®ãã¨ã§ããã§ããã
ãè©°ã¾ã£ã¦ãä»äºããããâãç¾å®éé¿ã§ ruby ã§éã¶ã
ã¨ããã³ã³ããçºåãã元サイトã«ããé«éã§è§£ãæ±ãã 60 è¡ã® python ã¹ã¯ãªããã ruby ã§æ¸ãã¦ã¿ã¾ãããã¾ãã¾ãã¾ Pythonã®ã³ã¼ãããã¯ã£ã¦ãã ãã§ãããããã
# -*- coding: utf-8 -*- require 'pp' class Array def sum self.inject(0) {|r, i| r += i } end end class KnightTour attr_reader :board def initialize(size) @board = [] @square_size = size end def in_range_and_empty(ty, tx) ty>=0 && tx>=0 && ty<@square_size && tx<@square_size && @board[ty][tx] == 0 end def fill(y, x, counter) @board[y][x] = counter exit 0 if counter == @square_size ** 2 empty_neighbours = [] jumps = [[-2, 1], [-1, 2], [1, 2], [2, 1], [2, -1], [1, -2], [-1, -2], [-2, -1]] jumps.each do |jump| ty, tx = y + jump[0], x + jump[1] empty_neighbours << [ty, tx] if in_range_and_empty(ty, tx) end empty_neighbours.sort_by {|v| jumps.map {|j| in_range_and_empty(v[0]+j[0], v[1]+j[1]) ? 1 : 0 }.sum }.each do |ty, tx| fill(ty, tx, counter+1) end @board[y][x] = 0 end def init_board 1.upto(@square_size) {|i| @board << [0] * @square_size } end def self.start(size) k = self.new(size) k.init_board k.fill(0, 0, 1) rescue SystemExit pp k.board else puts "no solution." end end if $0 == __FILE__ if ARGV[0].to_i == 0 puts "Usage: #{$0} <square size>" ããexit 0 end KnightTour.start(ARGV[0].to_i) end
çã£ããããããªããã©ãruby ã§ãã¡ããã© 60 è¡ã«ãªã£ãw
ãã£ãã 10x10 ãã¹ã®è§£ãåºãã¦ã¿ã¾ããã
/Users/kenkiti/% ruby knight_tour.rb 10 [[1, 38, 17, 42, 3, 36, 57, 48, 5, 34], [18, 41, 2, 37, 94, 49, 4, 35, 58, 47], [39, 16, 99, 50, 43, 56, 95, 60, 33, 6], [52, 19, 40, 93, 98, 91, 44, 63, 46, 59], [15, 100, 51, 90, 55, 96, 61, 86, 7, 32], [20, 53, 78, 97, 92, 87, 64, 45, 62, 71], [79, 14, 89, 54, 83, 76, 85, 72, 31, 8], [24, 21, 82, 77, 88, 73, 28, 65, 70, 67], [13, 80, 23, 26, 11, 84, 75, 68, 9, 30], [22, 25, 12, 81, 74, 27, 10, 29, 66, 69]]
ããä¸ç¬ã§è§£ãã§ããã¯ãããã¡ãªã¿ã«é ãæ¹ã®ã¹ã¯ãªããã ã¨æ°åç§ãããã¾ãããä¸ã¤æãå èªã¿ãã¦ãåããå ´æãå¤ãã«ã¼ãããé ã«æ¢ç´¢ãããã£ã¦å¦çãå ¥ããã ãã§ããããªã«éããªããã ãªããããã¡ãã£ã¨æåã
ãããããã®rubyã¹ã¯ãªããã31x31 ã§æ¢ç´¢ããã¨ãstack level too deep (SystemStackError) ã£ã¦åºã¡ãã£ããã ãã½ããã
追è¨
è²ã 調ã¹ã¦ãããruby 㯠Cã¹ã¿ãã¯ã使ã£ã¦ããã®ã§ãSystemStackError ãåé¿ããã«ã¯ ulimit 㧠stack size ãå¢ããã°ãããããªããããªãã㧠31x31 ãã¹ãå試ãã¡ãªã¿ã« stack ãå¢ããã¦ãã100x100ã¯ç¡çã§ãããæ®å¿µã
/Users/kenkiti/work% ulimit -aH -t: cpu time (seconds) unlimited -f: file size (blocks) unlimited -d: data seg size (kbytes) unlimited -s: stack size (kbytes) 65532 -c: core file size (blocks) unlimited -v: address space (kb) unlimited -l: locked-in-memory size (kb) unlimited -u: processes 532 -n: file descriptors unlimited /Users/kenkiti/work% ulimit -s 65532 /Users/kenkiti/work% time ruby knight_tour.rb 31 ruby knight_tour.rb 31 0.67s user 0.26s system 87% cpu 1.067 total