ludy 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,6 +1,26 @@
1
1
 
2
2
  ==============================
3
- ludy 0.0.7
3
+ ludy TODO
4
+ Proc#bind
5
+ multi
6
+ chain travel
7
+ method hook
8
+
9
+ ==============================
10
+ ludy 0.0.8, 2007.12.06
11
+
12
+ 1. ludy_ext:
13
+ added:
14
+ 1. Array#untranspose!
15
+ 2. Array#unzip!
16
+
17
+ changed:
18
+ 1. Kernel#curry support Symbol
19
+
20
+ 2. puzzle_generator added...
21
+
22
+ ==============================
23
+ ludy 0.0.7, 2007.10.08
4
24
 
5
25
  1. ludy_ext:
6
26
  added:
data/lib/ludy/ludy_ext.rb CHANGED
@@ -85,7 +85,9 @@ class Array
85
85
  }
86
86
  result
87
87
  end
88
- def unzip; self.untranspose.first; end
88
+ def untranspose!; replace untranspose; end
89
+ def unzip; untranspose.first; end
90
+ def unzip!; replace unzip; end
89
91
  end
90
92
 
91
93
  class Proc
@@ -113,7 +115,8 @@ end
113
115
  module Kernel
114
116
  def id a = nil; a.nil? ? self : a; end
115
117
  def curry
116
- class << self
118
+ result = self.kind_of?(Symbol) ? self.to_proc : self
119
+ class << result
117
120
  alias_method :orig_call, :call
118
121
  def call *args, &block
119
122
  if self.arity == -1
@@ -137,6 +140,6 @@ module Kernel
137
140
  end
138
141
  alias_method :[], :call
139
142
  end
140
- self
143
+ result
141
144
  end
142
145
  end
@@ -0,0 +1,33 @@
1
+
2
+ require File.join(File.dirname(__FILE__), 'misc')
3
+
4
+ module PuzzleGenerator
5
+
6
+ class Chain
7
+ include Enumerable
8
+ def initialize position = [0, 0], direct = Up, invoke = DefaultOption[:invoke]
9
+ @direct = direct
10
+ x, y = position
11
+ @data = case @direct
12
+ when Up : ([x]*invoke).zip((y...y+invoke).to_a)
13
+ when Right: (x...x+invoke).to_a.zip([y]*invoke)
14
+ when Left : (x-invoke+1..x).to_a.zip([y]*invoke)
15
+ end
16
+ end
17
+ def <=> rhs; @data <=> rhs.instance_variable_get('@data'); end
18
+ def == rhs; (self <=> rhs) == 0; end
19
+ def each &block; @data.each &block; self end
20
+ def [] index; @data[index]; end
21
+ def to_a; @data.clone; end
22
+ def up?; @direct == Up; end
23
+ def bound_ok? max_width, max_height
24
+ not @data.find{ |i|
25
+ i.first >= max_width ||
26
+ i.last >= max_height ||
27
+ i.first < 0 ||
28
+ i.last < 0
29
+ }
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,116 @@
1
+
2
+ pwd = File.dirname __FILE__
3
+
4
+ require File.join(pwd, 'misc')
5
+ require File.join(pwd, 'chain')
6
+ require File.join(pwd, 'map')
7
+
8
+ require 'rubygems'
9
+
10
+ gem 'ludy', '>=0.0.7' # for Array#combine
11
+ require 'ludy/ludy_ext'
12
+
13
+ gem 'facets', '>=2.0.0' # for lots of things
14
+ require 'facets/random' # for Array#pick
15
+
16
+ module PuzzleGenerator
17
+
18
+ # 1. put a chain
19
+ # 2. destroy a chain by chain
20
+ # 2. a. choose a position by last map
21
+ # 2. b. choose a direct from 3 direct (memo p+d)
22
+ # 2. c. check if the position + direct is ok? ok pass, failed choose again
23
+ # 2. d. goto 2
24
+
25
+ class ChainedMap
26
+ include DisplayMap, MapUtils
27
+ attr_reader :maps, :option
28
+ def initialize option = {}
29
+ @option = DefaultOption.merge option
30
+ raise_if_bad_argument
31
+ init_map
32
+ @result_map = begin next_level until @maps.size >= @option[:level]; put_fire_point
33
+ rescue GenerationFailed; $! end
34
+ end
35
+
36
+ private
37
+ def raise_if_bad_argument
38
+ msg = []
39
+ @option.each{ |name, value| msg << "#{name} should be greater than 1." if value <= 1 }
40
+ raise ArgumentError.new(msg.join("\n")) unless msg.empty?
41
+ end
42
+ def make_map; Map.new @option; end
43
+ def init_map
44
+ @maps = [make_map]
45
+ @result_map = make_map_array
46
+ @picked_chain = make_init_chains([(0..@option[:width]-@option[:invoke]), [0]].combos).pick
47
+ put_picked_chain_on @maps
48
+ resolve_map
49
+ end
50
+ # please make this init chain to variable length chain
51
+ def make_init_chains positions
52
+ positions.inject([]){ |result, pos| result << Chain.new(pos, Right, @option[:invoke]) }
53
+ end
54
+
55
+ def chain_ok?
56
+ raise GenerationFailed.new("ChainedMap: last result_map: #{@result_map.inspect}") if @picked_chain.nil?
57
+ @maps_preview = @maps.deep_clone
58
+ put_picked_chain_on @maps_preview
59
+
60
+ result = check_overlap_and_resolve_it &&
61
+ check_broken_except_last &&
62
+ check_answer_correctness(@result_map_preview) # need this if you gen variable length chain
63
+
64
+ @maps_preview = nil
65
+ @result_map_preview = nil
66
+ result
67
+ end
68
+ def next_level new_map = nil
69
+ @maps << (new_map || make_map)
70
+ chains = @maps[-1].break_chains @maps[-2], @result_map
71
+
72
+ @picked_chain = chains.pick!
73
+ @picked_chain = chains.pick! until chain_ok?
74
+
75
+ put_picked_chain_on @maps
76
+ @picked_chain = nil
77
+ resolve_map
78
+ end
79
+ def put_fire_point; next_level Map.new(@option.merge(:invoke => 1, :invoke_max => 1)); end
80
+ def put_picked_chain_on maps
81
+ maps.last.chains << @picked_chain
82
+ @picked_chain.each{ |pos|
83
+ x, y = pos
84
+ maps.each{ |map|
85
+ column = map[x]
86
+ column.replace(column[0...y] + column[y..-1].rotate)
87
+ }
88
+ maps.last[x, y] = maps.size
89
+ }
90
+ end
91
+ def check_overlap_and_resolve_it
92
+ @result_map_preview = @maps_preview.body.inject(make_map_array){ |result, map|
93
+ result.each_with_index{ |column, x|
94
+ column.each_with_index{ |value, y|
95
+ # assert one of them is zero or they are all zero
96
+ return false unless value * map[x, y] == 0
97
+ }
98
+ }
99
+ combine_map result, map
100
+ }
101
+ end
102
+ def check_broken_except_last
103
+ @maps_preview.body.all?{ |map|
104
+ result = true
105
+ map.each_with_index_2d{ |i, x, y|
106
+ result &&= !check_left_chain( map, x, y) &&
107
+ !check_right_chain(map, x, y) &&
108
+ !check_up_chain( map, x, y) &&
109
+ !check_down_chain( map, x, y)
110
+ }
111
+ result
112
+ }
113
+ end
114
+ end
115
+
116
+ end
@@ -0,0 +1,59 @@
1
+
2
+ require File.join(File.dirname(__FILE__), 'misc')
3
+
4
+ module PuzzleGenerator
5
+ class ColoredMap
6
+ include DisplayMap, MapUtils
7
+ def initialize chained_map, colors = (1..chained_map.option[:colors]).to_a
8
+ @result_map = []
9
+ @maps = []
10
+ @chained_map = chained_map
11
+ @option = @chained_map.option
12
+
13
+ debug_init if PuzzleGenerator.debug
14
+
15
+ chained_map.maps.each_with_index{ |map, index|
16
+ @maps << map.clone_with_map{ |color|
17
+ color == 0 ? 0 : colors[index % @option[:colors]]
18
+ }
19
+ }
20
+ resolve_map
21
+ @result_map = if check_no_invoke && strip_answer && check_answer_correctness
22
+ put_answer_back; @result_map
23
+ else
24
+ GenerationFailed.new("ColoredMap: last result_map: #{@result_map.inspect}")
25
+ end
26
+ end
27
+
28
+ private
29
+ def debug_init
30
+ @debug_answer = @chained_map.maps.last.each_with_index_2d{ |i, x, y| break i if i != 0 }
31
+ end
32
+ def check_no_invoke
33
+ m = Map.new :data => @result_map, :option => @option
34
+ m.each_with_index_2d{ |i, x, y|
35
+ return false if check_left_chain( m, x, y) ||
36
+ check_right_chain(m, x, y) ||
37
+ check_up_chain( m, x, y) ||
38
+ check_down_chain( m, x, y)
39
+ }
40
+ true
41
+ end
42
+ def strip_answer
43
+ @x, @y = @chained_map.maps.last.each_with_index_2d{ |i, x, y| break [x, y] if i != 0 }
44
+ # map = Map.new :data => @result_map, :option => @option
45
+ # return false unless !check_left_chain( map, @x, @y) &&
46
+ # !check_right_chain(map, @x, @y) &&
47
+ # !check_up_chain( map, @x, @y) &&
48
+ # !check_down_chain( map, @x, @y)
49
+ @answer_color = @result_map[@x][@y]
50
+ @result_map[@x][@y] = 0
51
+ true
52
+ end
53
+ def put_answer_back
54
+ @result_map[@x][@y] = @debug_answer || @answer_color
55
+ @x, @y, @answer_color = nil
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,135 @@
1
+
2
+ pwd = File.dirname __FILE__
3
+
4
+ require File.join(pwd, 'misc')
5
+ require File.join(pwd, 'chain')
6
+
7
+ require 'rubygems'
8
+
9
+ gem 'ludy', '>=0.0.7' # for Array#untranspose
10
+ require 'ludy/ludy_ext'
11
+
12
+ gem 'facets', '>=2.0.0' # for lots of things
13
+ require 'facets' # for Array#combos
14
+ require 'facets/random' # for Kernel#maybe
15
+
16
+ # a = [[1,2],[3,4],[5,6]]
17
+ # [a, [1,2,3]].combos
18
+ # => [[[1, 2], 1], [[1, 2], 2], [[1, 2], 3], [[3, 4], 1], [[3, 4], 2], [[3, 4], 3], [[5, 6], 1], [[5, 6], 2], [[5, 6], 3]]
19
+
20
+ module PuzzleGenerator
21
+
22
+ class Map
23
+ include DisplayMap, Enumerable
24
+ attr_reader :chains
25
+ def result_map; @data; end
26
+ def initialize option = {}
27
+ @option = DefaultOption.merge option
28
+ @data = @option[:data] || (Array.new(@option[:width])).map{ [0]*@option[:height] }
29
+ @chains = @option[:chains] || []
30
+ end
31
+ # TRAP!! view is not view, it's clone!!
32
+ # def [] x, y = (0..-1); @data[x][y]; end
33
+
34
+ # NOTICE!! this is not view (reference)
35
+ def [] x, y = nil
36
+ if y.nil?
37
+ @data[x]
38
+ else
39
+ if x.kind_of? Range
40
+ @data[x].transpose[y]
41
+ else
42
+ @data[x][y]
43
+ end
44
+ end
45
+ end
46
+ def []= x, y, v; @data[x][y] = v; end
47
+ def each_column_with_index; @data.each_with_index{ |column, index| yield column, index }; end
48
+ def each_column; @data.each{ |column| yield column }; end
49
+ def clone_with_map
50
+ Map.new @option.merge(
51
+ :data => @data.transpose.map{ |row| row.map{ |i| yield i } }.untranspose,
52
+ :chains => chains
53
+ )
54
+ end
55
+ def to_a; @data.clone; end
56
+ def each; @data.flatten.each{ |i| yield i }; end
57
+ def each_with_index_2d
58
+ @data.transpose.each_with_index{ |row, y| row.each_with_index{ |i, x| yield i, x, y } }
59
+ end
60
+ def break_chains map, result_map
61
+ @temp_map = map
62
+ @temp_result_map = result_map
63
+ result = []
64
+ map.each_column_with_index{ |column, ix|
65
+ column.each_with_index{ |y, iy| result << [ix, iy] if y != 0 }
66
+ } # e.g., [[0, 0], [1, 1]]
67
+ result = transform result,
68
+ :with_belows,
69
+ :with_directs,
70
+ :to_chains,
71
+ :strip_duplicated_chain,
72
+ :strip_out_bounded_chain,
73
+ :strip_overflow_chain,
74
+ :strip_floating_chain
75
+
76
+ @temp_result_map = nil
77
+ @temp_map = nil
78
+ result
79
+ end
80
+
81
+ private
82
+ def transform target, *funs; target = method(funs.shift)[target] until funs.empty?; target; end
83
+ def with_belows target
84
+ result = []
85
+ up_hack = 0 # @temp_map.chains.last.up? ? 1 : 0
86
+ target.each{ |pos|
87
+ x, y = pos
88
+ result.concat( ([x]*(y+1)).zip((up_hack..y).to_a) )
89
+ }
90
+ result.uniq
91
+ # e.g., [[0, 0], [[1, 0], [1, 1]]] =>
92
+ # [[0, 0], [1, 0], [1, 1]]
93
+ end
94
+ def with_directs target
95
+ # [target, [Up] + [Right, Left]*10].combos
96
+ [target, [Up, Right, Left]].combos
97
+ # e.g., [[[0, 0], Up], [[0, 0], Right], [[0, 0], Left], [[1, 0], Up], ...]
98
+ end
99
+ def to_chains target
100
+ target.map{ |pos| Chain.new pos.first, pos.last, gen_chain_length }
101
+ # e.g., [Chain#0x000, Chain#0x001, ...]
102
+ end
103
+ def gen_chain_length
104
+ @option[:invoke] + (maybe ? 0 : rand(@option[:invoke_max] - @option[:invoke] + 1))
105
+ end
106
+ def strip_duplicated_chain target
107
+ # target.uniq never works for non-num nor non-string :(
108
+ # target.sort.inject([]){ |r, i| r.last == i ? r : r<<i }
109
+ target.uniq_by{|i|i}
110
+ end
111
+ def strip_out_bounded_chain target
112
+ target.select{ |chain| chain.bound_ok? @option[:width], @option[:height] }
113
+ end
114
+ def strip_overflow_chain target
115
+ target.select{ |chain|
116
+ xs = Hash.new 0
117
+ chain.to_a.transpose.first.each{ |x| xs[x] += 1 }
118
+ xs.all?{ |pair|
119
+ x, count = pair
120
+ height(@temp_result_map[x]) + count <= @option[:height]
121
+ }
122
+ }
123
+ end
124
+ def strip_floating_chain target
125
+ target.select{ |chain|
126
+ chain.all?{ |pos|
127
+ x, y = pos # if the direct is up, then it's impossible floating.
128
+ chain.up? || !@temp_result_map[x][0...y].include?(0)
129
+ }
130
+ }
131
+ end
132
+ def height column; @option[:height] - column.count(0); end
133
+ end
134
+
135
+ end
@@ -0,0 +1,132 @@
1
+
2
+ require 'rubygems'
3
+ require 'facets' # for Array#deep_clone
4
+ # require 'ludy/ludy_ext' # for Kernel#curry
5
+
6
+ module PuzzleGenerator
7
+ Up, Right, Left = (0..2).to_a
8
+ DefaultOption = {:width => 6, :height => 10, :level => 4, :colors => 4,
9
+ :invoke => 3, :invoke_max => 5, :timeout => 5}
10
+ class GenerationFailed < RuntimeError; end
11
+ class << self
12
+ attr_writer :debug
13
+ def debug; @debug || false; end
14
+ end
15
+
16
+ module DisplayMap
17
+ attr_reader :result_map
18
+ def display_map
19
+ result_map.transpose.reverse_each{ |row| puts row.map{ |color| '%2d' % color }.join(' ') }
20
+ end
21
+ end
22
+
23
+ module MapUtils
24
+ def make_map_array; (Array.new(@option[:width])).map{ [0]*@option[:height] }; end
25
+ def resolve_map result_map = @result_map, maps = @maps
26
+ result_map.replace maps.inject(make_map_array){ |result, map|
27
+ combine_map result, map
28
+ }
29
+ end
30
+ def combine_map result, map
31
+ result.zip(map.to_a).map{ |columns|
32
+ orig, last = columns
33
+ orig.combine last
34
+ }
35
+ end
36
+ def check_answer_correctness result_map = @result_map
37
+ map = Map.new @option.merge(:data => result_map.deep_clone)
38
+ drop_blocks map # because of answer is stripped
39
+
40
+ @chained = true
41
+ while @chained
42
+ @chained = false
43
+ destory_chains map
44
+ drop_blocks map
45
+ end
46
+ @chained = nil
47
+
48
+ map.all?{ |i| i == 0 }
49
+ end
50
+ def destory_chains map
51
+ map.each_column_with_index{ |column, x|
52
+ column.each_with_index{ |value, y|
53
+ next if value == 0
54
+
55
+ left = check_left_chain map, x, y
56
+ right = check_right_chain map, x, y
57
+ up = check_up_chain map, x, y
58
+ down = check_down_chain map, x, y
59
+
60
+ # left.fill 0 unless left.nil?
61
+ # right.fill 0 unless right.nil?
62
+ # up.fill 0 unless up.nil?
63
+ # down.fill 0 unless down.nil?
64
+ left.size.times{ |offset|
65
+ map[x-offset, y] = 0
66
+ } unless left.nil?
67
+ right.size.times{ |offset|
68
+ map[x+offset, y] = 0
69
+ } unless right.nil?
70
+ up.size.times{ |offset|
71
+ map[x, y+offset] = 0
72
+ } unless up.nil?
73
+ down.size.times{ |offset|
74
+ map[x, y-offset] = 0
75
+ } unless down.nil?
76
+
77
+ @chained ||= left || right || up || down
78
+ }
79
+ }
80
+ end
81
+ def drop_blocks map
82
+ map.each_column{ |column| column.map!{ |i| i==0 ? nil : i }.compact!.pad!(@option[:height], 0) }
83
+ end
84
+ def check_left_chain map, x, y
85
+ # this should be rewrited
86
+ return nil if map[x, y] == 0
87
+ left = x - @option[:invoke] + 1
88
+ return nil if left < 0
89
+ # chain = map[left..x, y]
90
+ # chain if chain.all?{ |i| i == map[x, y] }
91
+ # map[0..x, y].inject([]){ |result, value| result << value if value == map[x, y] }
92
+ do_check_chain map[0..x, y].reverse, map[x, y]
93
+ end
94
+ def check_right_chain map, x, y
95
+ return nil if map[x, y] == 0
96
+ right = x + @option[:invoke] - 1
97
+ return nil if right >= @option[:width]
98
+ # chain = map[x..right, y]
99
+ # chain if chain.all?{ |i| i == map[x, y] }
100
+ do_check_chain map[x...@option[:width], y], map[x, y]
101
+ end
102
+ def check_up_chain map, x, y
103
+ return nil if map[x, y] == 0
104
+ up = y + @option[:invoke] - 1
105
+ return nil if up >= @option[:height]
106
+ # chain = map[x, y..up]
107
+ # chain if chain.all?{ |i| i == map[x, y] }
108
+ do_check_chain map[x, y...@option[:height]], map[x, y]
109
+ end
110
+ def check_down_chain map, x, y
111
+ return nil if map[x, y] == 0
112
+ down = y - @option[:invoke] - 1
113
+ return nil if down < 0
114
+ # chain = map[x, down..y]
115
+ # chain if chain.all?{ |i| i == map[x, y] }
116
+ do_check_chain map[x, 0..y].reverse, map[x, y]
117
+ end
118
+ # def check_chain target_color, result, value; result << value if value == target_color; end
119
+ def do_check_chain target, target_color
120
+ # target.inject([], &method(:check_chain).curry[target_color])
121
+ chain = target.inject([]){ |result, value|
122
+ if value == target_color
123
+ result << value
124
+ else
125
+ break result
126
+ end
127
+ }
128
+ chain.size >= @option[:invoke] ? chain : nil
129
+ end
130
+ end
131
+
132
+ end
@@ -0,0 +1,64 @@
1
+
2
+ require File.join(File.dirname(__FILE__), 'misc')
3
+ require File.join(File.dirname(__FILE__), 'chained_map')
4
+ require File.join(File.dirname(__FILE__), 'colored_map')
5
+
6
+ require 'rubygems'
7
+ require 'facets' # for Array#rotate
8
+ require 'facets/timer'
9
+
10
+ module PuzzleGenerator
11
+
12
+ class Puzzle
13
+ include DisplayMap
14
+ attr_reader :tried_times, :tried_duration
15
+ def initialize option = {}
16
+ @option = DefaultOption.merge option
17
+ @tried_times, @tried_duration = [0, 0], [0, 0]
18
+ end
19
+ def generate
20
+ raw_colors = (1..@option[:colors]).to_a
21
+ step_colors = raw_colors.rotate
22
+
23
+ make_chain
24
+ make_color raw_colors
25
+ until @result_color.result_map.kind_of? Array
26
+ if step_colors == raw_colors
27
+ make_chain
28
+ make_color raw_colors
29
+ step_colors = raw_colors.rotate
30
+ else
31
+ make_color step_colors
32
+ step_colors.rotate!
33
+ end
34
+ end
35
+
36
+ @result_map = @result_color.result_map
37
+ end
38
+
39
+ private
40
+ Chain, Color = 0, 1
41
+ def make_chain
42
+ begin
43
+ @result_chain =
44
+ PuzzleGenerator::generate(
45
+ @option[:timeout] - @tried_duration[Chain]){ ChainedMap.new @option }
46
+ ensure
47
+ update_info Chain, LastTriedInfo
48
+ end
49
+ end
50
+ def make_color colors
51
+ start = Time.now
52
+ begin
53
+ @result_color = ColoredMap.new @result_chain, colors
54
+ ensure
55
+ update_info Color, {:tried_times => 1, :tried_duration => Time.now - start}
56
+ end
57
+ end
58
+ def update_info index, info
59
+ @tried_times[index] += info[:tried_times]
60
+ @tried_duration[index] += info[:tried_duration]
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,35 @@
1
+
2
+ # alpha at 2007.10.14
3
+
4
+ require File.join(File.dirname(__FILE__), 'puzzle_generator', 'puzzle')
5
+
6
+ require 'rubygems'
7
+ require 'facets' # for Hash#reverse_merge
8
+ require 'facets/timer'
9
+
10
+ module PuzzleGenerator
11
+
12
+ def self.generate_chained_map option = {}; generate_klass ChainedMap, option; end
13
+ def self.generate_klass klass, option = {}
14
+ option.reverse_merge! :timeout => 5
15
+ generate(option[:timeout]){ klass.new option }
16
+ end
17
+
18
+ LastTriedInfo = {}
19
+ def self.generate timeout = 5, &generator
20
+ timer = Timer.new(timeout).start
21
+ tried_times = 1
22
+ begin
23
+ result = generator.call
24
+ until result.result_map.kind_of? Array
25
+ tried_times += 1
26
+ result = generator.call
27
+ end
28
+ ensure
29
+ timer.stop
30
+ LastTriedInfo.merge! :tried_times => tried_times, :tried_duration => timer.total_time
31
+ end
32
+ result
33
+ end
34
+
35
+ end
data/ludy.gemspec CHANGED
@@ -18,7 +18,7 @@ require 'rubygems'
18
18
 
19
19
  spec = Gem::Specification.new{|s|
20
20
  s.name = 'ludy'
21
- s.version = '0.0.7'
21
+ s.version = '0.0.8'
22
22
  s.author = 'Lin Jen-Shin(a.k.a. godfat)'
23
23
  s.email = 'strip number: 135godfat7911@246godfat.890org'
24
24
  s.homepage = 'http://ludy.rubyforge.org/'
data/test/tc_ludy_ext.rb CHANGED
@@ -76,6 +76,12 @@ class TestLudyExt < Test::Unit::TestCase
76
76
  assert_equal (0..4).to_a, lambda{|a,b,c,d,e|[a,b,c,d,e]}.curry[0][1][2][3][4]
77
77
  end
78
78
 
79
+ def test_symbol_curry
80
+ a = [1,2,3]
81
+ assert_equal nil, a.find(&:==.curry[0])
82
+ assert_equal 2, a.find(&:==.curry[2])
83
+ end
84
+
79
85
  def test_proc_chain
80
86
  f1 = lambda{|v| v+1}
81
87
  assert_equal 5, f1[4]
@@ -0,0 +1,177 @@
1
+
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'puzzle_generator')
3
+
4
+ PuzzleGenerator.debug = true
5
+ p = PuzzleGenerator::Puzzle.new :level => 15, :timeout => 600, :invoke_max => 5
6
+ begin
7
+ p.generate
8
+ p.display_map
9
+ rescue Timeout::Error
10
+ puts 'Timeout!!'
11
+ ensure
12
+ p p.tried_times
13
+ p p.tried_duration
14
+ end
15
+
16
+ # level => 7
17
+ # 0 0 0 0 0 0
18
+ # 0 0 0 0 0 0
19
+ # 0 0 3 0 0 0
20
+ # 0 0 1 0 0 0
21
+ # 1 3 4 0 0 0
22
+ # 2 1 1 0 0 0
23
+ # 2 3 2 0 0 0
24
+ # 3 4 3 0 0 0
25
+ # 3 1 2 4 0 0
26
+ # 2 4 2 1 0 0
27
+
28
+ # level => 15
29
+ # 0 0 1 0 0 0
30
+ # 2 0 2 1 0 0
31
+ # 1 0 4 1 0 0
32
+ # 2 0 3 3 1 0
33
+ # 2 4 1 4 4 0
34
+ # 3 2 4 2 2 1
35
+ # 4 1 1 3 3 2
36
+ # 3 3 2 3 4 3
37
+ # 3 1 3 4 1 2
38
+ # 2 3 4 1 4 2
39
+
40
+ # level => 7
41
+ # 0 0 0 0 0 0
42
+ # 0 0 0 0 0 0
43
+ # 0 0 0 0 0 0
44
+ # 0 0 0 0 0 0
45
+ # 0 0 1 0 0 0
46
+ # 0 0 2 2 0 0
47
+ # 0 1 3 4 4 0
48
+ # 1 2 4 1 1 0
49
+ # 3 3 2 2 3 1
50
+ # 2 2 3 3 4 3
51
+ # [20, 9]
52
+ # [1.630587, 0.151272]
53
+
54
+ # level => 10
55
+ # 0 0 1 1 0 0
56
+ # 0 0 1 2 0 0
57
+ # 0 0 2 3 0 0
58
+ # 0 0 2 3 0 0
59
+ # 0 0 3 4 0 0
60
+ # 0 1 4 1 0 0
61
+ # 0 2 1 3 4 0
62
+ # 2 2 2 2 1 0
63
+ # 2 3 1 3 2 4
64
+ # 4 4 1 4 3 2
65
+ # [28, 1]
66
+ # [3.26917, 0.020366]
67
+
68
+ # level => 12
69
+ # 0 2 1 0 0 0
70
+ # 0 2 2 0 0 0
71
+ # 0 3 3 1 0 0
72
+ # 0 4 3 2 0 0
73
+ # 0 4 4 2 0 4
74
+ # 0 1 4 3 1 1
75
+ # 0 4 1 1 2 1
76
+ # 0 3 2 2 1 2
77
+ # 0 3 4 4 3 1
78
+ # 2 3 4 3 4 1
79
+ # [68, 1]
80
+ # [6.194671, 0.055699]
81
+
82
+ # level => 13
83
+ # 0 3 1 0 0 0
84
+ # 0 2 1 1 0 0
85
+ # 0 3 3 2 1 2
86
+ # 0 3 2 1 1 4
87
+ # 0 4 2 3 3 4
88
+ # 0 1 3 3 2 1
89
+ # 0 4 2 4 3 1
90
+ # 0 4 2 1 4 2
91
+ # 0 3 1 4 4 1
92
+ # 2 3 2 2 1 1
93
+ # [10, 1]
94
+ # [1.97002, 0.030499]
95
+
96
+ # level => 7
97
+ # 0 0 0 0 0 0
98
+ # 0 0 0 2 0 0
99
+ # 0 0 0 3 0 0
100
+ # 0 0 0 4 0 0
101
+ # 0 0 0 1 0 0
102
+ # 0 0 0 2 0 0
103
+ # 0 1 1 3 0 0
104
+ # 0 2 2 4 3 0
105
+ # 0 4 4 3 4 3
106
+ # 1 2 2 3 1 1
107
+ # [53, 17]
108
+ # [4.614123, 0.264156]
109
+
110
+ # level => 14
111
+ # 0 0 0 0 0 0
112
+ # 0 0 1 0 0 0
113
+ # 1 0 4 0 2 0
114
+ # 1 0 2 4 3 0
115
+ # 2 1 3 2 3 0
116
+ # 2 3 1 4 4 1
117
+ # 3 1 4 3 3 2
118
+ # 2 4 1 4 3 2
119
+ # 3 2 2 1 1 3
120
+ # 2 4 4 1 1 2
121
+ # [123, 1]
122
+ # [14.940386, 0.077763]
123
+
124
+ # level => 15
125
+ # 0 0 0 0 1 0
126
+ # 0 0 2 0 2 0
127
+ # 0 0 1 0 3 0
128
+ # 0 4 4 1 4 1
129
+ # 2 2 4 2 3 3
130
+ # 3 2 2 3 1 1
131
+ # 3 3 1 4 4 2
132
+ # 4 3 1 3 4 2
133
+ # 2 4 2 1 1 3
134
+ # 3 3 1 1 4 2
135
+ # [3650, 17]
136
+ # [464.755704, 1.220837]
137
+
138
+ # level => 15
139
+ # 0 2 0 0 1 0
140
+ # 0 4 2 1 3 0
141
+ # 4 3 3 2 2 0
142
+ # 2 4 3 3 2 0
143
+ # 1 2 2 3 3 0
144
+ # 1 1 4 2 3 0
145
+ # 2 1 3 4 16 0
146
+ # 1 2 2 1 3 1
147
+ # 4 1 4 4 2 3
148
+ # 1 1 3 4 1 1
149
+ # [1626, 1]
150
+ # [159.004594, 0.035997]
151
+
152
+ # level => 17 => broken...
153
+ # 0 2 0 1 1 0
154
+ # 0 4 2 2 3 0
155
+ # 4 <3 3 3> 2 1
156
+ # 2 4 3 3 2 2
157
+ # 1 2 2 2 3 3
158
+ # 1 1 4 4 3 2
159
+ # 2 1 3 1 1 2
160
+ # 1 2 2 1 3 1
161
+ # 4 1 4 4 2 3
162
+ # 1 1 3 4 1 1
163
+ # hacked from above XD
164
+
165
+ # level => 15
166
+ # 1 0 0 0 0 0
167
+ # 3 1 1 0 3 0
168
+ # 4 2 4 4 1 0
169
+ # 4 3 2 2 4 0
170
+ # 1 3 2 3 2 0
171
+ # 1 2 3 1 2 0
172
+ # 2 4 2 4 3 0
173
+ # 1 3 3 2 3 0
174
+ # 1 3 1 1 16 4
175
+ # 4 1 2 2 3 1
176
+ # [1139, 1]
177
+ # [115.270095, 0.031929]
metadata CHANGED
@@ -1,33 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
3
- specification_version: 1
4
2
  name: ludy
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.0.7
7
- date: 2007-10-08 00:00:00 +08:00
8
- summary: Aims to extend Ruby standard library, providing some useful tools that's not existed in the standard library.
9
- require_paths:
10
- - lib
11
- email: "strip number: 135godfat7911@246godfat.890org"
12
- homepage: http://ludy.rubyforge.org/
13
- rubyforge_project:
14
- description:
15
- autorequire: ludy
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: false
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: 0.0.8
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Lin Jen-Shin(a.k.a. godfat)
8
+ autorequire: ludy
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2007-12-06 00:00:00 +08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: "strip number: 135godfat7911@246godfat.890org"
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
31
24
  files:
32
25
  - lib/lib
33
26
  - lib/lib/amulti.rb
@@ -46,6 +39,14 @@ files:
46
39
  - lib/ludy/y_combinator.rb
47
40
  - lib/ludy/z_combinator.rb
48
41
  - lib/ludy.rb
42
+ - lib/puzzle_generator
43
+ - lib/puzzle_generator/chain.rb
44
+ - lib/puzzle_generator/chained_map.rb
45
+ - lib/puzzle_generator/colored_map.rb
46
+ - lib/puzzle_generator/map.rb
47
+ - lib/puzzle_generator/misc.rb
48
+ - lib/puzzle_generator/puzzle.rb
49
+ - lib/puzzle_generator.rb
49
50
  - test/tc_callstack.rb
50
51
  - test/tc_curry.rb
51
52
  - test/tc_dice.rb
@@ -56,6 +57,7 @@ files:
56
57
  - test/tc_variable.rb
57
58
  - test/tc_y_combinator.rb
58
59
  - test/tc_z_combinator.rb
60
+ - test/test_puzzle.rb
59
61
  - test/ts_ludy.rb
60
62
  - CHANGES
61
63
  - lib
@@ -64,17 +66,31 @@ files:
64
66
  - NOTICE
65
67
  - README
66
68
  - test
67
- test_files:
68
- - test/ts_ludy.rb
69
+ has_rdoc: false
70
+ homepage: http://ludy.rubyforge.org/
71
+ post_install_message:
69
72
  rdoc_options: []
70
73
 
71
- extra_rdoc_files: []
72
-
73
- executables: []
74
-
75
- extensions: []
76
-
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: "0"
87
+ version:
77
88
  requirements: []
78
89
 
79
- dependencies: []
80
-
90
+ rubyforge_project:
91
+ rubygems_version: 0.9.5
92
+ signing_key:
93
+ specification_version: 2
94
+ summary: Aims to extend Ruby standard library, providing some useful tools that's not existed in the standard library.
95
+ test_files:
96
+ - test/ts_ludy.rb