Last active
August 29, 2015 14:19
-
-
Save lithtle/879a300a28f4d3fefbd8 to your computer and use it in GitHub Desktop.
"第30回オフラインリアルタイムどう書くの問題" 解いてみた ref: http://qiita.com/lithtle/items/25f465f7a28393f99755
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: sjis | |
# | |
# とある世界のタクシー料金を計算する | |
# Author:: lithtle | |
# Created_At:: 2015-04-21 | |
# Link:: http://nabetani.sakura.ne.jp/hena/ord30taxi/ | |
# 都市の地点と経路 | |
CITY = { | |
enlightened: [:A, :B, :C, :AB, :AC, :BG, :CF, :BC], | |
registance: [:D, :E, :F, :G, :AD, :CD, :DE, :DF, :EG, :FG] | |
}.freeze | |
# 各地点間の距離 | |
DISTANTCE = { | |
AB: 1090, | |
AC: 180, | |
AD: 540, | |
BC: 960, | |
BG: 1270, | |
CD: 400, | |
CF: 200, | |
DE: 720, | |
DF: 510, | |
EG: 1050, | |
FG: 230 | |
}.freeze | |
# 各都市でのタクシー設定 | |
TAXI_SETTING = { | |
enlightened: {min_dist: 995, min_fee: 400, per_meter: 200, per_fee: 60}, | |
registance: {min_dist: 845, min_fee: 350, per_meter: 200, per_fee: 50} | |
}.freeze | |
# 経路から都市を判定する | |
# == Args | |
# _route_: 経路または地点、文字列 | |
# == Returns | |
# 覚醒派か開放派か | |
def get_city(route) | |
if CITY[:enlightened].any?{ |e| e == route.to_sym || e == route.reverse.to_sym } | |
:enlightened | |
elsif CITY[:registance].any?{ |e| e == route.to_sym || e == route.reverse.to_sym } | |
:registance | |
else | |
raise "未定義の経路指定" | |
end | |
end | |
# とある世界のタクシー料金を求める | |
# == Args | |
# _route_: 料金を計算したいルート | |
# == Returns | |
# 料金 | |
def get_taxi_fee(route) | |
n = 2 | |
start_point = route[0] | |
# 各地点の累積距離を求める | |
route = route.scan(/\w/).each_cons(n).map(&:join) # => ["AB", "BC", "CD"] | |
each_dist = route.map{ |e| DISTANTCE[e.to_sym] || DISTANTCE[e.reverse.to_sym] } # => [100, 200, 300] | |
integrated_distantce = each_dist.collect.with_index{ |e, i| each_dist[0..i].reduce(:+) } # => [100, 300, 600] | |
# 初期設定(初乗り運賃、初乗り料金)を求める | |
running_disatnce, total_fee = [ | |
TAXI_SETTING[get_city(start_point)][:min_dist], | |
TAXI_SETTING[get_city(start_point)][:min_fee] | |
] | |
# タクシー⊂(^ω^)⊃ブーン | |
total_distance = integrated_distantce[-1] | |
while running_disatnce < total_distance | |
# 到着したら終了 | |
if running_disatnce > total_distance | |
break | |
end | |
# 現在位置からどちらの都市かを判定し運賃を加算 | |
current_pos = route[integrated_distantce.find_index{ |e| e > running_disatnce }] | |
total_fee += TAXI_SETTING[get_city(current_pos)][:per_fee] | |
# 200m すすむ | |
running_disatnce += 200 | |
end | |
total_fee | |
end | |
# てすと | |
def test | |
DATA.read.split("\n").map{ |e| | |
e.gsub(/\s+/, ",").split(",") | |
}.each do |item| | |
i, route, expect = item | |
actual = get_taxi_fee(route) | |
ok = actual == expect.to_i ? "ok" : "ng" | |
puts "%2d: %-10s => res: %5s == %-5s : exp => %s" % [i.to_i, route, actual, expect, ok] | |
end | |
end | |
if $0 == __FILE__ | |
test | |
end | |
__END__ | |
0 ADFC 510 | |
1 CFDA 500 | |
2 AB 460 | |
3 BA 460 | |
4 CD 400 | |
5 DC 350 | |
6 BG 520 | |
7 GB 530 | |
8 FDA 450 | |
9 ADF 450 | |
10 FDACB 750 | |
11 BCADF 710 | |
12 EDACB 800 | |
13 BCADE 810 | |
14 EGFCADE 920 | |
15 EDACFGE 910 | |
16 ABCDA 960 | |
17 ADCBA 1000 | |
18 BADCFGB 1180 | |
19 BGFCDAB 1180 | |
20 CDFC 460 | |
21 CFDC 450 | |
22 ABGEDA 1420 | |
23 ADEGBA 1470 | |
24 CFGB 640 | |
25 BGFC 630 | |
26 ABGEDFC 1480 | |
27 CFDEGBA 1520 | |
28 CDFGEDABG 1770 | |
29 GBADEGFDC 1680 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment