From 1ddffb5a27ac4eba4a3f4203f96b2bc7ee155b8d Mon Sep 17 00:00:00 2001 From: pikesley Date: Tue, 21 Nov 2017 21:50:32 +0000 Subject: [PATCH] Better --- Makefile | 5 ++- lib/ruby/constrained_towers.rb | 59 +++++++++++++++++---------------- spec/constrained_towers_spec.rb | 32 ++++++++---------- 3 files changed, 47 insertions(+), 49 deletions(-) diff --git a/Makefile b/Makefile index 9f7b1c1..701e9a5 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,10 @@ lint: flake8 *py tests/ install: - bundle + virtualenv . + . bin/activate + pip install -r requirements.txt + bundle install solve: ./towers console --discs $(or $(discs),3) diff --git a/lib/ruby/constrained_towers.rb b/lib/ruby/constrained_towers.rb index 4da07a3..d054e03 100644 --- a/lib/ruby/constrained_towers.rb +++ b/lib/ruby/constrained_towers.rb @@ -1,17 +1,42 @@ class ConstrainedTowers < Towers - @@directions = {} - def initialize discs super @ternary = ConstrainedTowers.ternarise @count, @discs + @directions = {} + @stacks[0].each do |disc| + @directions[disc] = :right + end end def move - flip = Towers.diff ConstrainedTowers.ternarise(@count, @discs), + @flip = Towers.diff ConstrainedTowers.ternarise(@count, @discs), ConstrainedTowers.ternarise(@count += 1, @discs) - source = Towers.find_disc flip, @stacks + @source = find_disc + + @stacks[find_stack].push @stacks[@source].pop + end - @stacks[ConstrainedTowers.find_adjacent_stack flip, source, @stacks].push @stacks[source].pop + def find_disc + @stacks.each_with_index do |stack, index| + return index if stack.index @flip + end + end + + def find_stack + case @source + when 0 + @directions[@flip] = :right + return 1 + when 2 + @directions[@flip] = :left + return 1 + when 1 + if @directions[@flip] == :right + return 2 + else + return 0 + end + end end def binary @@ -36,28 +61,4 @@ def inspect def ConstrainedTowers.ternarise value, width '%0*d' % [width, value.to_s(3)] end - - def ConstrainedTowers.find_adjacent_stack disc, source, stacks - begin - direction = @@directions[disc] - rescue KeyError - @@directions[disc] = :right - direction = right - end - - case source - when 0 - @@directions[disc] = :right - return 1 - when 2 - @@directions[disc] = :left - return 1 - when 1 - if @@directions[disc] == :right - return 2 - else - return 0 - end - end - end end diff --git a/spec/constrained_towers_spec.rb b/spec/constrained_towers_spec.rb index 72e1d6f..aec65b6 100644 --- a/spec/constrained_towers_spec.rb +++ b/spec/constrained_towers_spec.rb @@ -12,27 +12,21 @@ expect(Towers.diff '012', '020').to eq 1 end end - context 'adjacent stacks' do - context 'noddy cases' do - it 'moves from left to centre' do - stacks = [[], [], []] - expect(ConstrainedTowers.find_adjacent_stack 0, 0, stacks).to eq 1 - end - - it 'moves from right to centre' do - stacks = [[], [], []] - expect(ConstrainedTowers.find_adjacent_stack 0, 2, stacks).to eq 1 - end - end - end - it 'follows the rules' do - towers = ConstrainedTowers.new 4 + context 'follow the rules' do + [2, 3, 4, 5, 6, 7, 8].each do |discs| + it "plays by the rules with %s discs" % discs do + towers = ConstrainedTowers.new discs + goal = towers.stacks[0].clone + until towers.solved do + towers.move + towers.stacks.each do |stack| + expect(stack.sort.reverse).to eq stack + end + end - until towers.solved do - towers.move - towers.stacks.each do |stack| - expect(stack.sort.reverse).to eq stack + expect(towers.stacks[2]).to eq goal + expect(towers.count).to eq (3 ** discs) - 1 end end end