LoginSignup
1
1

More than 5 years have passed since last update.

「オフラインリアルタイムどう書く第30回(とある世界のタクシー料金)」の問題を解いてみた

Posted at

横浜へなちょこプログラミング勉強会にて過去に出題されたとある世界のタクシー料金を解いてみた。
回答にかかった時間は40分程度。

[from,to].sort.join.to_symが非常に気に食わないが、sortしなくてもよいようにROUTEに逆順も持つのはおかしな話なので妥協した。

class Taxi
  FIRSTRIDE = [[995, 400], [845, 350]]
  ROUTE     = {
    AB: [1090, 0], AC: [180,  0], AD: [540,  1], BC: [960,  0], BG: [1270, 0],
    CD: [400,  1], CF: [200,  0], DE: [720,  1], DF: [510,  1], EG: [1050, 1],
    FG: [230,  1]
  }
  ADD_FARE  = [60, 50]

  def drive input
    input.each_char.each_cons(2).inject(FIRSTRIDE[[?A, ?B, ?C].include?(input[0]) ? 0 : 1]){|(left, fare), (from, to)|
      range, meter_type = ROUTE[[from,to].sort.join.to_sym]
      c = range <= left ? 0 : ((range - left) / 200.0).ceil
      [(left + 200 * c) - range, fare + ADD_FARE[meter_type] * c]
    }[1]
  end
end

test = <<_TEST
/*0*/ test( "ADFC", "510" );    
/*1*/ test( "CFDA", "500" );    
/*2*/ test( "AB", "460" );    
/*3*/ test( "BA", "460" );    
/*4*/ test( "CD", "400" );    
/*5*/ test( "DC", "350" );    
/*6*/ test( "BG", "520" );    
/*7*/ test( "GB", "530" );    
/*8*/ test( "FDA", "450" );    
/*9*/ test( "ADF", "450" );    
/*10*/ test( "FDACB", "750" );    
/*11*/ test( "BCADF", "710" );    
/*12*/ test( "EDACB", "800" );    
/*13*/ test( "BCADE", "810" );    
/*14*/ test( "EGFCADE", "920" );    
/*15*/ test( "EDACFGE", "910" );    
/*16*/ test( "ABCDA", "960" );    
/*17*/ test( "ADCBA", "1000" );    
/*18*/ test( "BADCFGB", "1180" );    
/*19*/ test( "BGFCDAB", "1180" );    
/*20*/ test( "CDFC", "460" );    
/*21*/ test( "CFDC", "450" );    
/*22*/ test( "ABGEDA", "1420" );    
/*23*/ test( "ADEGBA", "1470" );    
/*24*/ test( "CFGB", "640" );    
/*25*/ test( "BGFC", "630" );    
/*26*/ test( "ABGEDFC", "1480" );    
/*27*/ test( "CFDEGBA", "1520" );    
/*28*/ test( "CDFGEDABG", "1770" );    
/*29*/ test( "GBADEGFDC", "1680" );
_TEST

require 'minitest/autorun'

describe 'Taxi' do
  taxi = Taxi.new
  test.split("\n").each do |line|
    t, n, input, expect = line.match(/^\/\*(\d+)\*\/\s*test\(\s*"([^"]+)",\s*"([^"]+)"\s*\);*\s*$/).to_a
    it input do
      assert_equal expect, taxi.drive(input).to_s
    end
  end
end
1
1
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
1
1