0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

「オフラインリアルタイムどう書く第28回(十字の壁がそそり立つ世界の中を君は螺旋状に歩く)」の問題を解いてみた

Posted at

横浜へなちょこプログラミング勉強会にて過去に出題された十字の壁がそそり立つ世界の中を君は螺旋状に歩くを解いてみた。
回答にかかった時間は90分程度。

別実装を30分程度で書いたのだが、それだと追加問題に対応できなかった。
追加問題にも対応するため再度実装しなおしたのがこの実装となる。
追加問題についても答えが載っていたので、他のテストケースと同じ形式に直してテストケースに追加する形を取っている。
CrossWallWorld#roundingeach内でbreakすることで本来selfが返ってくるはずなのに数値を返したり、CrossWallWorld#goinjectで数字を回しておきながらbreakSymbolを返すというなんとも気持ち悪い実装をしている。
読み返してもやっぱり気持ち悪いのだが、他にいいやり方も思いつかないのでこのままにしている。

class CrossWallWorld
  def travel input
    wall, days = input.split ":"
    @north, @east, @south, @west = wall.split(",").map &:to_i
    go *rounding(days.to_i)
  end

  private

  def rounding days
    c = (1..Float::INFINITY).each{|c, _|
      r = @north * 2 + @east * 2 + @south * 2 + @west * 2 + c * 8
      break c if days < r
      days -= r
    }
    [days, c]
  end

  def go days, count
    [
      [@east,  :E], [count * 2, :S], [@east,      :W],
      [@south, :S], [count * 2, :W], [@south,     :N],
      [@west,  :W], [count * 2, :N], [@west,      :E],
      [@north, :N], [count * 2, :E], [@north - 1, :S],
      [@east,  :E]
    ].inject(0){|d, (len, way)|
      break way if days < (d + len)
      d + len
    }.to_s
  end
end

test = <<_TEST
/*0*/ test( "2,3,5,4:85", "S" );    
/*1*/ test( "1,2,3,4:1", "E" );    
/*2*/ test( "1,2,3,4:2", "S" );    
/*3*/ test( "1,2,3,4:3", "S" );    
/*4*/ test( "1,2,3,4:4", "W" );    
/*5*/ test( "1,2,3,4:27", "E" );    
/*6*/ test( "1,2,3,4:63", "E" );    
/*7*/ test( "1,2,3,4:40", "W" );    
/*8*/ test( "1,4,3,2:40", "S" );    
/*9*/ test( "3,3,3,3:30", "S" );    
/*10*/ test( "3,3,3,3:31", "E" );    
/*11*/ test( "3,3,3,3:32", "E" );    
/*12*/ test( "3,3,3,3:70", "S" );    
/*13*/ test( "3,3,3,3:71", "E" );    
/*14*/ test( "3,3,3,3:72", "E" );    
/*15*/ test( "1,1,1,1:7", "N" );    
/*16*/ test( "1,2,1,1:7", "W" );    
/*17*/ test( "1,6,1,1:7", "S" );    
/*18*/ test( "1,8,1,1:7", "E" );    
/*19*/ test( "1,1,1,1:30", "N" );    
/*20*/ test( "1,2,1,1:30", "W" );    
/*21*/ test( "1,5,1,1:30", "S" );    
/*22*/ test( "1,8,1,1:30", "E" );    
/*23*/ test( "9,9,9,9:99", "W" );    
/*24*/ test( "5,6,3,8:3", "E" );    
/*25*/ test( "5,8,1,1:11", "W" );    
/*26*/ test( "2,8,1,2:18", "S" );    
/*27*/ test( "3,2,3,1:20", "N" );    
/*28*/ test( "3,3,8,1:28", "N" );    
/*29*/ test( "2,5,1,2:32", "E" );    
/*30*/ test( "2,5,1,6:33", "E" );    
/*31*/ test( "1,2,5,7:34", "N" );    
/*32*/ test( "3,6,5,6:36", "E" );    
/*33*/ test( "6,2,8,1:39", "S" );    
/*34*/ test( "3,1,2,3:41", "W" );    
/*35*/ test( "1,1,3,4:45", "W" );    
/*36*/ test( "1,3,1,2:46", "N" );    
/*37*/ test( "4,4,4,4:49", "W" );    
/*38*/ test( "3,1,4,4:55", "N" );    
/*39*/ test( "6,6,2,1:56", "W" );    
/*40*/ test( "3,2,1,2:59", "S" );    
/*41*/ test( "2,7,7,1:60", "S" );    
/*42*/ test( "3,1,1,1:63", "N" );    
/*43*/ test( "4,6,4,1:78", "E" );    
/*44*/ test( "7,5,3,6:79", "W" );    
/*45*/ test( "7,8,3,1:81", "E" );    
/*46*/ test( "3,2,5,2:82", "S" );    
/*47*/ test( "1,1,3,4:84", "N" );    
/*48*/ test( "7,4,1,5:88", "S" );    
/*49*/ test( "3,6,5,3:89", "S" );    
/*50*/ test( "1,4,2,3:92", "N" );    
/*51*/ test( "1,3,4,5:93", "W" );    
/*52*/ test( "2,4,8,1:94", "W" );    
/*53*/ test( "3,6,1,7:99", "S" );
/*54*/ test( "1234,2345,3456,4567:978593417", "E" );
/*55*/ test( "1234,2345,3456,4567:978593418", "S" );
/*56*/ test( "31415,92653,58979,32384:9812336139", "W" );
/*57*/ test( "31415,92653,58979,32384:9812336140", "S" );
/*58*/ test( "314159,265358,979323,84626:89099331642", "S" );
/*59*/ test( "314159,265358,979323,84626:89099331643", "W" );
_TEST

require 'minitest/autorun'

describe 'CrossWallWorld' do
  test.split("\n").each do |line|
    t, n, input, expect = line.match(/^\/\*(\d+)\*\/\s*test\(\s*"([^"]+)",\s*"([^"]+)"\s*\);*\s*$/).to_a
    world = CrossWallWorld.new
    it input do
      assert_equal expect, world.travel(input)
    end
  end
end
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?