#coding: utf-8
# 単位付1元1次方程式を解く。
# CodeIQ q1058 「中学入試から:単位のある計算」
class UnitsEquation
class Formula
def initialize(formula, unknown='')
@formula = formula
@unknown = unknown
end
def parse
sign_before = '+'
@formula.scan(/([-+]?)(\d+|#{@unknown})([^-+\d#{@unknown}]+)/).map do |sign, num_str, unit|
sign = sign_before if sign.empty?
sign_before = sign
{sign: sign, num_str: num_str, unit: unit}
end
end
end
attr_reader :equation, :answer
def initialize(equation, unknown)
@equation = equation
@unknown = unknown
end
def solve
left_formula, right_formula = @equation.split('=').map{|formula| Formula.new(formula, @unknown).parse}
unit_nums = left_formula + right_formula.map{|r| r[:sign] = (r[:sign] == '-' ? '+' : '-'); r}
# 方程式の中で単位が換算出来ない場合の処理
# return unless unit_nums.uniq{|un| @@unit_conversion_table[un[:unit]][:base_unit]}.size == 1
unknown = unit_nums.find{|un| un[:num_str] == @unknown}
unit_nums.delete(unknown)
minimum_unit_nums = unit_nums.map do |unit_num|
num = unit_num[:num_str].to_i
num = -num if unit_num[:sign] == unknown[:sign]
num * @@unit_conversion_table[unit_num[:unit]][:scale]
end
@answer = minimum_unit_nums.inject(&:+) / @@unit_conversion_table[unknown[:unit]][:scale]
end
@@unit_conversion_table =
DATA.map(&:chomp).each_with_object({}) do |equation, memo|
unit_nums = equation.split('=').each_with_object({}) do |formula, mm|
Formula.new(formula).parse.each{|f| mm[f[:unit]] = f[:num_str].to_i}
end
base_unit, base_unit_scale = unit_nums.max_by{|unit, scale| scale}
unit_nums.each{|unit, scale| memo[unit] = {scale: base_unit_scale / scale, base_unit: base_unit}}
end
@@unit_conversion_table.default = {base_unit: :base_unit}
end
if $0 == __FILE__
ARGF.each do |line|
no, *equ = line.chomp.split("\t")
equation = equ.map{|e| UnitsEquation.new(e, '□')}
equation.each{|e| e.solve}
if equation.uniq(&:answer).size == 1
puts "#{no}: Correct."
else
puts "#{no}: Wrong."
puts equation.map{|e| " equation: #{e.equation}, answer: #{e.answer}"}
end
end
end
__END__
1km=1000m=100000cm=1000000mm
1kg=1000g=1000000mg
1日=24時間=1440分=86400秒
I2NvZGluZzogdXRmLTgKCiMg5Y2Y5L2N5LuYMeWFgzHmrKHmlrnnqIvlvI/jgpLop6PjgY/jgIIKIyBDb2RlSVEgcTEwNTgg44CM5Lit5a2m5YWl6Kmm44GL44KJ77ya5Y2Y5L2N44Gu44GC44KL6KiI566X44CNCgpjbGFzcyBVbml0c0VxdWF0aW9uCiAgY2xhc3MgRm9ybXVsYQogICAgZGVmIGluaXRpYWxpemUoZm9ybXVsYSwgdW5rbm93bj0nJykKICAgICAgQGZvcm11bGEgPSBmb3JtdWxhCiAgICAgIEB1bmtub3duID0gdW5rbm93bgogICAgZW5kCgogICAgZGVmIHBhcnNlCiAgICAgIHNpZ25fYmVmb3JlID0gJysnCiAgICAgIEBmb3JtdWxhLnNjYW4oLyhbLStdPykoXGQrfCN7QHVua25vd259KShbXi0rXGQje0B1bmtub3dufV0rKS8pLm1hcCBkbyB8c2lnbiwgbnVtX3N0ciwgdW5pdHwKICAgICAgICBzaWduID0gc2lnbl9iZWZvcmUgaWYgc2lnbi5lbXB0eT8KICAgICAgICBzaWduX2JlZm9yZSA9IHNpZ24KICAgICAgICB7c2lnbjogc2lnbiwgbnVtX3N0cjogbnVtX3N0ciwgdW5pdDogdW5pdH0KICAgICAgZW5kCiAgICBlbmQKICBlbmQKCiAgYXR0cl9yZWFkZXIgOmVxdWF0aW9uLCA6YW5zd2VyCgogIGRlZiBpbml0aWFsaXplKGVxdWF0aW9uLCB1bmtub3duKQogICAgQGVxdWF0aW9uID0gZXF1YXRpb24KICAgIEB1bmtub3duICA9IHVua25vd24KICBlbmQKCiAgZGVmIHNvbHZlCiAgICBsZWZ0X2Zvcm11bGEsIHJpZ2h0X2Zvcm11bGEgPSBAZXF1YXRpb24uc3BsaXQoJz0nKS5tYXB7fGZvcm11bGF8IEZvcm11bGEubmV3KGZvcm11bGEsIEB1bmtub3duKS5wYXJzZX0KICAgIHVuaXRfbnVtcyA9IGxlZnRfZm9ybXVsYSArIHJpZ2h0X2Zvcm11bGEubWFwe3xyfCByWzpzaWduXSA9IChyWzpzaWduXSA9PSAnLScgPyAnKycgOiAnLScpOyByfQoKICAgICMg5pa556iL5byP44Gu5Lit44Gn5Y2Y5L2N44GM5o+b566X5Ye65p2l44Gq44GE5aC05ZCI44Gu5Yem55CGCiAgICAjIHJldHVybiB1bmxlc3MgdW5pdF9udW1zLnVuaXF7fHVufCBAQHVuaXRfY29udmVyc2lvbl90YWJsZVt1bls6dW5pdF1dWzpiYXNlX3VuaXRdfS5zaXplID09IDEKCiAgICB1bmtub3duID0gdW5pdF9udW1zLmZpbmR7fHVufCB1bls6bnVtX3N0cl0gPT0gQHVua25vd259CiAgICB1bml0X251bXMuZGVsZXRlKHVua25vd24pCgogICAgbWluaW11bV91bml0X251bXMgPSB1bml0X251bXMubWFwIGRvIHx1bml0X251bXwKICAgICAgbnVtID0gdW5pdF9udW1bOm51bV9zdHJdLnRvX2kKICAgICAgbnVtID0gLW51bSBpZiB1bml0X251bVs6c2lnbl0gPT0gdW5rbm93bls6c2lnbl0KICAgICAgbnVtICogQEB1bml0X2NvbnZlcnNpb25fdGFibGVbdW5pdF9udW1bOnVuaXRdXVs6c2NhbGVdCiAgICBlbmQKCiAgICBAYW5zd2VyID0gbWluaW11bV91bml0X251bXMuaW5qZWN0KCY6KykgLyBAQHVuaXRfY29udmVyc2lvbl90YWJsZVt1bmtub3duWzp1bml0XV1bOnNjYWxlXQogIGVuZAoKICBAQHVuaXRfY29udmVyc2lvbl90YWJsZSA9CiAgREFUQS5tYXAoJjpjaG9tcCkuZWFjaF93aXRoX29iamVjdCh7fSkgZG8gfGVxdWF0aW9uLCBtZW1vfAogICAgdW5pdF9udW1zID0gZXF1YXRpb24uc3BsaXQoJz0nKS5lYWNoX3dpdGhfb2JqZWN0KHt9KSBkbyB8Zm9ybXVsYSwgbW18CiAgICAgIEZvcm11bGEubmV3KGZvcm11bGEpLnBhcnNlLmVhY2h7fGZ8IG1tW2ZbOnVuaXRdXSA9IGZbOm51bV9zdHJdLnRvX2l9CiAgICBlbmQKICAgIGJhc2VfdW5pdCwgYmFzZV91bml0X3NjYWxlID0gdW5pdF9udW1zLm1heF9ieXt8dW5pdCwgc2NhbGV8IHNjYWxlfQogICAgdW5pdF9udW1zLmVhY2h7fHVuaXQsIHNjYWxlfCBtZW1vW3VuaXRdID0ge3NjYWxlOiBiYXNlX3VuaXRfc2NhbGUgLyBzY2FsZSwgYmFzZV91bml0OiBiYXNlX3VuaXR9fQogIGVuZAogIEBAdW5pdF9jb252ZXJzaW9uX3RhYmxlLmRlZmF1bHQgPSB7YmFzZV91bml0OiA6YmFzZV91bml0fQoKZW5kCgoKCmlmICQwID09IF9fRklMRV9fCiAgQVJHRi5lYWNoIGRvIHxsaW5lfAogICAgbm8sICplcXUgPSBsaW5lLmNob21wLnNwbGl0KCJcdCIpCiAgICBlcXVhdGlvbiA9IGVxdS5tYXB7fGV8IFVuaXRzRXF1YXRpb24ubmV3KGUsICfilqEnKX0KICAgIGVxdWF0aW9uLmVhY2h7fGV8IGUuc29sdmV9CiAgICBpZiBlcXVhdGlvbi51bmlxKCY6YW5zd2VyKS5zaXplID09IDEKICAgICAgcHV0cyAiI3tub306IENvcnJlY3QuIgogICAgZWxzZQogICAgICBwdXRzICIje25vfTogV3JvbmcuIgogICAgICBwdXRzIGVxdWF0aW9uLm1hcHt8ZXwgIiAgZXF1YXRpb246ICN7ZS5lcXVhdGlvbn0sIGFuc3dlcjogI3tlLmFuc3dlcn0ifQogICAgZW5kCiAgZW5kCmVuZAoKX19FTkRfXwoxa209MTAwMG09MTAwMDAwY209MTAwMDAwMG1tCjFrZz0xMDAwZz0xMDAwMDAwbWcKMeaXpT0yNOaZgumWkz0xNDQw5YiGPTg2NDAw56eSCg==
VDAxCTNtMjBjbS0zbTEwY20t4pahbW09NW1tCeKWoWtnPTk1MDAwZwpUMDIJMmtnKzUwMGcr4pahZz0za2cyMDBnCeKWoW09NzAwMDAwbW0KVDAzCTEya2crMWtnNTAwZyvilqFnPTEza2c3MDBnCTcyMDAwMOenkj3ilqHmmYLplpMKVDA0CTLmmYLplpMzMOWIhi3ilqHmmYLplpM9OTDliIYJ4paha209MTAwMG0KVDA1CTHml6Ut4pah5YiGPTIz5pmC6ZaTMjDliIYJNDAwMDBtbT3ilqFtClQwNgkz5pelLeKWoeenki03MeaZgumWkzU55YiGMzDnp5I9N+enkgkyMzAwMGc94paha2cKVDA3CTIz5pmC6ZaTMzDliIYrMjnliIYrNjDnp5I94pah5pelCeKWoWttPTEwMDBtClQwOAkx5pelKzIz5pmC6ZaTMTXliIYr4pah5YiGKzEyMOenkj0y5pelCTQzMDAwbT3ilqFrbQpUMDkJMWttLTFtLTFjbS0xbW094pahbW0J4paha2c9OTk4OTg5MDAwZwpUMTAJM20yMGNtLTVjbTJtbS0yMGNtOG1tK+KWoWNtPTMxMmNtCeKWoWttPTE4MDAwbQpUMTEJMeaXpS0x5pmC6ZaTLTHliIYtMeenkj3ilqHnp5IJMjk3ODYwNDAw56eSPeKWoeaZgumWkwpUMTIJMWtnLTFnPeKWoWcJ4pah5pelPTIzOTc25pmC6ZaTClQxMwnilqHml6UtMeaZgumWky0x5YiGLTHnp5I9ODI3Mznnp5IJMTAwMGc94paha2cKVDE0CTRrbS0zOTk1bS00ODBjbS3ilqFtbT0yMGNtCeKWoWttPTBtClQxNQkxMm0zMGNtLTdtNDNjbS00NWNtMm1tLeKWoW1tPTNtODBjbQkxNDgzMuaZgumWkz3ilqHml6UKVDE2CTBtK+KWoWttPTBtbQkwZz3ilqFrZwpUMTcJMjTmmYLplpMr4pah5YiGPTHml6UJ4pah5pelPTDmmYLplpMKVDE4CTRjbTNtbSvilqFrbSs1bW09NDhtbQkw5YiGPeKWoeaZgumWkwpUMTkJ4pah5YiGKzI05pmC6ZaTKzfml6UrMTTliIYzNOenkj03Nzc2MzTnp5IJ4pah5pelPTIwNTM0NDDliIYKVDIwCTEyMuaXpSsyMOaZgumWkzM15YiGMjTnp5I94pah56eSCTEwNjE0OTI0MDAwZz3ilqFrZwpUMjEJMjQwa20tMjE4OTg3bS04NzgwY20tNzc2NDhtbT3ilqFtbQnilqHml6U9NTAwMzQxMjQ45pmC6ZaTClQyMgkxMjDliIYrNDbliIYt4pah5YiGPTHmmYLplpMxOeWIhgk3MjDliIYrOTMwMOWIhi00ODAw5YiGPeKWoeaZgumWkwpUMjMJMTAwa2crMzJrZy0zNmtnPeKWoWtnCTI5Nm1nLTEwMG1nLeKWoW1nPTEwMG1nClQyNAk1MzM0NDg2NTBtbS3ilqFrbS01MjEyMjY1MG1tPTIwMzMyNjAwMG1tCTI3MDg0MOenkivilqHmmYLplpMrNjgzODMy56eSPTIy5pelMTXmmYLplpMxMeWIhjEy56eSClQyNQk4M20r4pahbSsxMzBtPTYyNm0JMTM3a20yNjBtNTVjbTJtbSszNzc5MTAwMDBtbS3ilqFrbT0xMDJrbTE3MG01NWNtMm1tClQyNgkxMDAwa2crMTAwMGtnLTE2MDlrZz3ilqFrZwk05pmC6ZaTKzPmmYLplpMxNOWIhi00M+WIhj3ilqHliIYKVDI3CTcwNGtnNzIwZy0yMzVrZy00a2c3MjBnPeKWoWtnCTE0MjXml6UtNDgw5pelLTQ4MOaXpT3ilqHml6UKVDI4CTI0NjI5NzkzNTAwbWcrNDM1OTQ3MzQwMG1nLTEyNzgza2cyNjZnOTAwbWc94paha2cJ4paha2c9MTYyMDYwMDAwMDBtZwpUMjkJNzg5bS0yNTBtLTI0NG094pahbQkyNzUyMTBnK+KWoWtnKzEyNjM4MGc9Njk2NTkwZwpUMzAJNjI1Y20t4pahY20tMzAwY209MW0JMjE5a20xMDBtK+KWoWttKzE1M2ttPTU5NzEwMG0KVDMxCTE1NjQyMDBnLTQ5OGtnLTQwNDIwMGc94paha2cJMzMx5pelM+aZgumWkzM05YiGKzY1OOaXpTIw5pmC6ZaTNTjliIYt4pah5pelPTMyOOaXpTMy5YiGClQzMgkyMTlrZzY0NWc2MDBtZy3ilqFrZz02NmtnNjQ1ZzYwMG1nCTE0ODM4NzQyNG1tK+KWoWttPTMwMTM4NzQyNG1tClQzMwk1N20rMTA0NjBjbSvilqFtPTMyMzYwY20JMTBjbSvilqFtbT0yNmNtMm1tClQzNAkxNDM35pelM+aZgumWkznliIYt4pah5pelLTMxNzMzMTAw56eSPTcwNzE4NDDnp5IJMTE1NzcwMOWIhis3NDg2ODDliIYt4pah5pelPTQ4MzY2MOWIhgpUMzUJNDYwODgxNuenkivilqHml6U9Njc5NDAwMTbnp5IJNTBjbSsxMDAwbW0t4pahbW09NzZjbTdtbQpUMzYJMjIwa2czMDBnKzYwa2czNTVnLeKWoWtnPTUwNjU1ZwnilqFrbSsxMjdrbTUwMW0xMGNtPTM1NzUwMTEwMG1tClQzNwk1MDg45YiGKzTml6Uz5pmC6ZaTLTU1MDjliIY94pah5pmC6ZaTCTEzNzY1MTg4MG1nLTI4a2czMDBnMjkwbWct4paha2c9MTdrZzM1MWc1OTBtZwpUMzgJNzI0NjBtLeKWoWttPTRrbTQ2MG0JMTjmmYLplpMxNOWIhisy5pelM+aZgumWkzQw5YiGK+KWoeaZgumWkz00OTY0NDDnp5IKVDM5CTEyMDAwbWcrMjhnLeKWoWc9MG1nCTk4a20xMjVtNzFjbS0zODMxMzAwY20tMTk4MTI3MWNtPeKWoWttClQ0MAk1NTIyMG1tKzM4OTkxMG1tK+KWoW09MWttMjVtMTNjbQkxNjA0OTA056eSKzE5NTcyNDnnp5It4pah5pmC6ZaTPTE35pelMeaZgumWkzI55YiGMTPnp5IK
T01 3m20cm-3m10cm-□mm=5mm □kg=95000g
T02 2kg+500g+□g=3kg200g □m=700000mm
T03 12kg+1kg500g+□g=13kg700g 720000秒=□時間
T04 2時間30分-□時間=90分 □km=1000m
T05 1日-□分=23時間20分 40000mm=□m
T06 3日-□秒-71時間59分30秒=7秒 23000g=□kg
T07 23時間30分+29分+60秒=□日 □km=1000m
T08 1日+23時間15分+□分+120秒=2日 43000m=□km
T09 1km-1m-1cm-1mm=□mm □kg=998989000g
T10 3m20cm-5cm2mm-20cm8mm+□cm=312cm □km=18000m
T11 1日-1時間-1分-1秒=□秒 297860400秒=□時間
T12 1kg-1g=□g □日=23976時間
T13 □日-1時間-1分-1秒=82739秒 1000g=□kg
T14 4km-3995m-480cm-□mm=20cm □km=0m
T15 12m30cm-7m43cm-45cm2mm-□mm=3m80cm 14832時間=□日
T16 0m+□km=0mm 0g=□kg
T17 24時間+□分=1日 □日=0時間
T18 4cm3mm+□km+5mm=48mm 0分=□時間
T19 □分+24時間+7日+14分34秒=777634秒 □日=2053440分
T20 122日+20時間35分24秒=□秒 10614924000g=□kg
T21 240km-218987m-8780cm-77648mm=□mm □日=500341248時間
T22 120分+46分-□分=1時間19分 720分+9300分-4800分=□時間
T23 100kg+32kg-36kg=□kg 296mg-100mg-□mg=100mg
T24 533448650mm-□km-52122650mm=203326000mm 270840秒+□時間+683832秒=22日15時間11分12秒
T25 83m+□m+130m=626m 137km260m55cm2mm+377910000mm-□km=102km170m55cm2mm
T26 1000kg+1000kg-1609kg=□kg 4時間+3時間14分-43分=□分
T27 704kg720g-235kg-4kg720g=□kg 1425日-480日-480日=□日
T28 24629793500mg+4359473400mg-12783kg266g900mg=□kg □kg=16206000000mg
T29 789m-250m-244m=□m 275210g+□kg+126380g=696590g
T30 625cm-□cm-300cm=1m 219km100m+□km+153km=597100m
T31 1564200g-498kg-404200g=□kg 331日3時間34分+658日20時間58分-□日=328日32分
T32 219kg645g600mg-□kg=66kg645g600mg 148387424mm+□km=301387424mm
T33 57m+10460cm+□m=32360cm 10cm+□mm=26cm2mm
T34 1437日3時間9分-□日-31733100秒=7071840秒 1157700分+748680分-□日=483660分
T35 4608816秒+□日=67940016秒 50cm+1000mm-□mm=76cm7mm
T36 220kg300g+60kg355g-□kg=50655g □km+127km501m10cm=357501100mm
T37 5088分+4日3時間-5508分=□時間 137651880mg-28kg300g290mg-□kg=17kg351g590mg
T38 72460m-□km=4km460m 18時間14分+2日3時間40分+□時間=496440秒
T39 12000mg+28g-□g=0mg 98km125m71cm-3831300cm-1981271cm=□km
T40 55220mm+389910mm+□m=1km25m13cm 1604904秒+1957249秒-□時間=17日1時間29分13秒