fork download
  1. =begin
  2.  
  3. 600 蟻人間 ◆T6xkBnTXz7B0 2021/04/15(木) 20:54:26.73 ID:IlyHVFTA
  4.   お題: ここに3つのタンクA,B,Cがある。それぞれの最大容量は20L, 15L, 10Lである。初め、Aには水15Lが入っていて、Bには水10L入っていて、
  5.   Cは空っぽだ。重力により、水は2L/sの速さでAからBに流入し、3L/sの速さでBからCに流入する。
  6.   このような水の流れとタンク内容量の変化を再現してCがいっぱいになったときのAとBの内容量を求めよ。
  7.  
  8. 601 蟻人間 ◆T6xkBnTXz7B0 2021/04/15(木) 21:05:03.04 ID:PVf346K4
  9.   >>600 訂正と追記。
  10.   s/重力により/ポンプにより/
  11.  
  12.   方程式は使ってはならない。必ずシミュレーションなどで再現すること。
  13.  
  14. =end
  15.  
  16.  
  17.  
  18. class Tank
  19. attr_reader :water
  20. @max = 0
  21. @outSpeef = 0
  22. def initialize(m,w,s)
  23. @max = m
  24. @water = w
  25. @outSpeef = s
  26. self
  27. end
  28. def in( w )
  29. @water = [ @max, @water + w ].min
  30. self
  31. end
  32. def out
  33. out = [ @outSpeef, @water ].min
  34. @water -= out
  35. out
  36. end
  37. def >>(exp)
  38. exp.in( self.out )
  39. end
  40. end
  41.  
  42. $scale = 6 # 2.lcm( 3 )
  43. tankA = Tank.new( 20 * $scale, 15 * $scale, 2 )
  44. tankB = Tank.new( 15 * $scale, 10 * $scale, 3 )
  45. tankC = Tank.new( 10 * $scale, 0 * $scale, 0 )
  46. tanks = [ tankA, tankB, tankC ]
  47.  
  48. def printTank( sec, tanks )
  49. unless sec
  50. puts " sec A B C"
  51. return
  52. end
  53. puts " %6.3f, %s" % [ sec.fdiv($scale), tanks.map{|x| ' %5.2f' % [x.water.fdiv($scale)] }.join(', ') ]
  54. end
  55.  
  56. sec = 0
  57. printTank( nil, nil )
  58. loop do
  59. printTank( sec, tanks )
  60. break unless tankC.water != 10 * $scale
  61. # break unless tankA.water != 0 || tankB.water != 0
  62. tankA >> tankB >> tankC
  63. sec += 1
  64. end
  65. printTank( nil, nil )
  66. puts
  67. puts "sec = #{Rational(sec,$scale)} ~= #{sec.fdiv($scale)}"
  68. puts "Tank A = #{Rational(tankA.water,$scale)} ~= #{tankA.water.fdiv($scale)}"
  69. puts "Tank B = #{Rational(tankB.water,$scale)} ~= #{tankB.water.fdiv($scale)}"
  70. puts "Tank C = #{Rational(tankC.water,$scale)} ~= #{tankC.water.fdiv($scale)}"
  71.  
Success #stdin #stdout 0.01s 6232KB
stdin
Standard input is empty
stdout
   sec     A       B       C
  0.000,  15.00,  10.00,   0.00
  0.167,  14.67,   9.83,   0.50
  0.333,  14.33,   9.67,   1.00
  0.500,  14.00,   9.50,   1.50
  0.667,  13.67,   9.33,   2.00
  0.833,  13.33,   9.17,   2.50
  1.000,  13.00,   9.00,   3.00
  1.167,  12.67,   8.83,   3.50
  1.333,  12.33,   8.67,   4.00
  1.500,  12.00,   8.50,   4.50
  1.667,  11.67,   8.33,   5.00
  1.833,  11.33,   8.17,   5.50
  2.000,  11.00,   8.00,   6.00
  2.167,  10.67,   7.83,   6.50
  2.333,  10.33,   7.67,   7.00
  2.500,  10.00,   7.50,   7.50
  2.667,   9.67,   7.33,   8.00
  2.833,   9.33,   7.17,   8.50
  3.000,   9.00,   7.00,   9.00
  3.167,   8.67,   6.83,   9.50
  3.333,   8.33,   6.67,  10.00
   sec     A       B       C

sec    = 10/3 ~= 3.3333333333333335
Tank A = 25/3 ~= 8.333333333333334
Tank B = 20/3 ~= 6.666666666666667
Tank C = 10/1 ~= 10.0