# http://nabetani.sakura.ne.jp/hena/ordf02in2rec/
# by @Nabetani
# 百万×百万対応解
# 包含原理で計算する
require "minitest/autorun"
class TestRunner < Minitest::Test
def setup
# 2つの矩形が重なっているか判定
overlapping = ->r1, r2{
r1[0] <= r2[2] && r2[0] <= r1[2] && r1[1] <= r2[3] && r2[1] <= r1[3]
}
# 2つの矩形が重なっている部分の面積を計算
calc_area = ->r1, r2{
([r1[2], r2[2]].min - [r1[0], r2[0]].max + 1) * ([r1[3], r2[3]].min - [r1[1], r2[1]].max + 1)
}
# 2つの矩形に共通する部分の矩形を生成
calc_co_rect = ->r1, r2{
[[r1[0], r2[0]].max, [r1[1], r2[1]].max, [r1[2], r2[2]].min, [r1[3], r2[3]].min]
}
@f = ->input{
rects = input.split(?/).map{|r|r.scan(/\d+/).map(&:to_i)}
rects.combination(2).inject(0){|sum, (r1, r2)|
sum + (overlapping[r1, r2] ? calc_area[r1, r2] : 0)
} - 3 * (overlapping[r1 = rects[0], r2 = rects[1]] && overlapping[r3 = rects[2], r4 = calc_co_rect[r1, r2]] ? calc_area[r3, r4] : 0)
}
end
def test_run
DATA.each{|data|
input, expected = data.chomp.match(/test\(\s*\"(.+)\",\s*\"(.+)\"\s*\)/)[1..2]
assert_equal expected.to_i, @f[input]
}
end
end
__END__
/*0*/ test( "0,0-999999,999999/0,0-999999,999999/0,0-999999,999999", "0" );
/*1*/ test( "0,0-999999,999999/0,0-0,999999/1,0-999999,999999", "1000000000000" );
/*2*/ test( "655822,899981-788586,907370/262080,47983-540321,834515/327083,392880-474728,550251", "23235346312" );
/*3*/ test( "332855,375381-953091,410430/311649,171289-637710,912139/113674,426911-658531,763493", "120432128946" );
/*4*/ test( "718118,613550-931221,983155/84495,98906-214393,787796/159096,14702-416478,360207", "14449477996" );
/*5*/ test( "809,351021-589370,525004/161241,390394-302773,958450/78299,230856-310951,941900", "80430542457" );
/*6*/ test( "140869,614312-559945,677721/424067,131309-645701,709237/22556,149538-902108,566473", "101023697750" );
/*7*/ test( "655941,129163-859649,985280/446717,159679-977047,839232/172790,559592-492587,741630", "146781576755" );
/*8*/ test( "17192,474077-715775,513703/177518,159867-395312,530025/331315,181585-695872,274046", "14547945541" );
/*9*/ test( "898603,252482-932681,923548/158284,561187-881317,881298/291114,46375-975112,431448", "6099016393" );
/*10*/ test( "460763,311625-742309,415024/708446,250395-980176,802067/190828,650489-798525,855977", "17155773920" );
/*11*/ test( "76405,197443-189085,423768/218793,635517-608524,914533/68011,184211-238902,819853", "29209657076" );
/*12*/ test( "602585,166640-862797,212028/844554,91101-971982,642729/130166,132319-619895,387625", "1613805895" );
/*13*/ test( "570213,345485-759193,657391/214801,517728-943628,936004/412700,32310-853707,623589", "65618672419" );
/*14*/ test( "251546,411491-781481,812128/271544,210234-536793,313835/174707,164436-353882,432689", "10699927141" );
/*15*/ test( "768602,340406-876104,451915/531084,97975-614595,607952/297417,452002-545499,950992", "2248189616" );
/*16*/ test( "824147,181473-928495,890221/673583,148595-734839,191460/532038,851156-892611,920296", "2674653690" );
/*17*/ test( "507676,577270-927426,825282/385783,352947-643538,691954/243369,815194-385405,859966", "15581448155" );
/*18*/ test( "388419,439549-745538,669102/262281,742072-609988,970128/533573,137288-596245,670546", "14386837842" );
/*19*/ test( "663239,518782-856702,589433/758115,84450-903932,642088/337647,24284-583025,565986", "6965439376" );
/*20*/ test( "191239,779501-419016,973110/461699,265809-619813,400896/295357,343268-995965,426583", "9112009335" );
/*21*/ test( "481413,405591-580708,502557/548827,255673-775012,641036/426629,627433-838039,929163", "6168536238" );
/*22*/ test( "9920,498487-514382,683023/226772,29017-628472,646705/311712,341208-824675,813994", "86680486267" );
/*23*/ test( "607788,403841-668184,518365/91263,688091-637506,857258/24319,559457-663076,919412", "92407004992" );
/*24*/ test( "77084,799236-139505,979891/754122,279472-794364,868062/150527,608666-281632,750541", "0" );
/*25*/ test( "169296,83569-620267,759983/460604,265256-945013,954017/317013,98311-745837,121044", "85884450562" );
/*26*/ test( "129661,44653-592189,297222/219053,537474-316753,980074/157470,756816-370610,907480", "14720121165" );
/*27*/ test( "297941,386287-716792,725006/241452,450763-567051,962750/195744,679475-346109,722435", "74159512604" );
/*28*/ test( "168144,237088-329400,634496/10381,564404-835828,912626/449243,161014-923398,676107", "54486189445" );
/*29*/ test( "107162,121311-807174,529239/344730,331975-894427,731597/581880,770044-619288,914307", "91224212925" );
/*30*/ test( "412012,102200-935128,257111/111516,225570-444846,539065/784025,129787-872324,570078", "12278479070" );
/*31*/ test( "800011,636792-837944,845950/7799,3048-945539,551037/197775,295503-609840,482184", "76925305012" );
/*32*/ test( "127131,26333-180762,397870/27576,261600-816030,833590/301519,411147-645517,557943", "57806507475" );
/*33*/ test( "32758,293294-988342,514135/468,543068-318854,548069/27211,318362-114542,567550", "16448211254" );
/*34*/ test( "100410,724118-597622,745585/183566,413277-751642,938721/672678,271783-953373,854704", "43746337696" );
/*35*/ test( "617281,172835-638934,558464/725936,550832-893293,968391/243005,644233-783866,774370", "7539024478" );
/*36*/ test( "306059,461338-761333,479832/59110,334011-979200,367681/201997,335634-587440,531481", "17556869402" );
/*37*/ test( "198441,770394-533721,965743/7845,436240-747623,621749/345710,713519-465402,866708", "11528231295" );
/*38*/ test( "856417,156222-995259,695178/552046,8773-879184,347237/114065,393927-827128,775960", "4349052288" );
/*39*/ test( "298522,174473-586813,447826/513017,410991-576739,639088/180342,283427-453079,776103", "27756635628" );
/*40*/ test( "676607,92015-788738,889720/351236,32426-799213,692704/334633,87130-927627,121184", "76070680990" );
/*41*/ test( "112863,136827-415321,945235/278661,676383-304033,860715/404074,160748-970146,761914", "11439007625" );