| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | --- | 
					
						
							|  |  |  | id: 5900f3d21000cf542c50fee5 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:00:51 -07:00
										 |  |  | title: 'Problema 102: Contenção Triangular' | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | challengeType: 5 | 
					
						
							|  |  |  | forumTopicId: 301726 | 
					
						
							|  |  |  | dashedName: problem-102-triangle-containment | 
					
						
							|  |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # --description--
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:00:51 -07:00
										 |  |  | Três pontos distintos são colocados aleatoriamente em um plano cartesiano, para o qual -1000 ≤ x, y ≤ 1000, de modo que um triângulo seja formado. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:00:51 -07:00
										 |  |  | Considere o seguinte exemplo com dois triângulos: | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | const exampleTriangles = [ | 
					
						
							|  |  |  |   [[-340, 495], [-153, -910], [835, -947]], | 
					
						
							|  |  |  |   [[-175, 41], [-421, -714], [574, -645]] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:00:51 -07:00
										 |  |  | É possível verificar que o primeiro triângulo contém a origem, ao passo que o segundo triângulo não. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:00:51 -07:00
										 |  |  | Usando o array `triangles` contendo coordenadas de triângulos, descubra o número de triângulos para os quais o interior contém a origem. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | # --hints--
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:00:51 -07:00
										 |  |  | `triangleContainment(exampleTriangles)` deve retornar um número. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | assert(typeof triangleContainment(_exampleTriangles) === 'number'); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:00:51 -07:00
										 |  |  | `triangleContainment(exampleTriangles)` deve retornar `1`. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | assert.strictEqual(triangleContainment(_exampleTriangles), 1); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:00:51 -07:00
										 |  |  | `triangleContainment(testTriangles1)` deve retornar `19`. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | assert.strictEqual(triangleContainment(_testTriangles1), 19); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:00:51 -07:00
										 |  |  | `triangleContainment(testTriangles2)` deve retornar `228`. | 
					
						
							| 
									
										
										
										
											2021-06-15 00:49:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | assert.strictEqual(triangleContainment(_testTriangles2), 228); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # --seed--
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## --after-user-code--
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | const _exampleTriangles = [ | 
					
						
							|  |  |  |   [[-340, 495], [-153, -910], [835, -947]], | 
					
						
							|  |  |  |   [[-175, 41], [-421, -714], [574, -645]] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const _testTriangles1 = [ | 
					
						
							|  |  |  |   [[-866,121],[-928,358],[459,-843]],[[-568,-631],[-352,-580],[-349,189]],[[-737,849],[-963,-486],[-662,970]],[[135,334],[-967,-71],[-365,-792]],[[789,21],[-227,51],[990,-275]],[[240,412],[-886,230],[591,256]],[[-609,472],[-853,-754],[959,661]],[[401,521],[521,314],[929,982]],[[-499,784],[-208,71],[-302,296]],[[-557,-948],[-553,-526],[-864,793]],[[270,-626],[828,44],[37,14]],[[-412,224],[617,-593],[502,699]],[[41,-908],[81,562],[-849,163]],[[165,917],[761,-197],[331,-341]],[[-687,314],[799,755],[-969,648]],[[-164,25],[578,439],[-334,-576]],[[213,535],[874,-177],[-551,24]],[[-689,291],[-795,-225],[-496,-125]],[[465,461],[558,-118],[-568,-909]],[[567,660],[-810,46],[-485,878]],[[-147,606],[685,-690],[-774,984]],[[568,-886],[-43,854],[-738,616]],[[-800,386],[-614,585],[764,-226]],[[-518,23],[-225,-732],[-79,440]],[[-173,-291],[-689,636],[642,-447]],[[-598,-16],[227,410],[496,211]],[[-474,-930],[-656,-321],[-420,36]],[[-435,165],[-819,555],[540,144]],[[-969,149],[828,568],[394,648]],[[65,-848],[257,720],[-625,-851]],[[981,899],[275,635],[465,-877]],[[80,290],[792,760],[-191,-321]],[[-605,-858],[594,33],[706,593]],[[585,-472],[318,-35],[354,-927]],[[-365,664],[803,581],[-965,-814]],[[-427,-238],[-480,146],[-55,-606]],[[879,-193],[250,-890],[336,117]],[[-226,-322],[-286,-765],[-836,-218]],[[-913,564],[-667,-698],[937,283]],[[872,-901],[810,-623],[-52,-709]],[[473,171],[717,38],[-429,-644]],[[225,824],[-219,-475],[-180,234]],[[-530,-797],[-948,238],[851,-623]],[[85,975],[-363,529],[598,28]],[[-799,166],[-804,210],[-769,851]],[[-687,-158],[885,736],[-381,-461]],[[447,592],[928,-514],[-515,-661]],[[-399,-777],[-493,80],[-544,-78]],[[-884,631],[171,-825],[-333,551]],[[191,268],[-577,676],[137,-33]],[[212,-853],[709,798],[583,-56]],[[-908,-172],[-540,-84],[-135,-56]],[[303,311],[406,-360],[-240,811]],[[798,-708],[824,59],[234,-57]],[[491,693],[-74,585],[-85,877]],[[509,-65],[-936,329],[-51,722]],[[-122,858],[-52,467],[-77,-609]],[[850,760],[547,-495],[-953,-952]],[[-460,-541],[890,910],[286,724]],[[-914,843],[-579,-983],[-387,-460]],[[989,-171],[-877,-326],[-899,458]],[[846,175],[-915,540],[-1000,-982]],[[-852,-920],[-306,496],[530,-18]],[[338,-991],[160,85],[-455,-661]],[[-186,-311],[-460,-563],[-231,-414]],[[-932,-302],[959,597],[793,748]],[[-366,-402],[-788,-279],[514,53]],[[-940,-956],[447,-956],[211,-285]],[[564,806],[-911,-914],[934,754]],[[575,-858],[-277,15],[409,-714]] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const _testTriangles2 = [ | 
					
						
							|  |  |  |   [[-340,495],[-153,-910],[835,-947]],[[-175,41],[-421,-714],[574,-645]],[[-547,712],[-352,579],[951,-786]],[[419,-864],[-83,650],[-399,171]],[[-429,-89],[-357,-930],[296,-29]],[[-734,-702],[823,-745],[-684,-62]],[[-971,762],[925,-776],[-663,-157]],[[162,570],[628,485],[-807,-896]],[[641,91],[-65,700],[887,759]],[[215,-496],[46,-931],[422,-30]],[[-119,359],[668,-609],[-358,-494]],[[440,929],[968,214],[760,-857]],[[-700,785],[838,29],[-216,411]],[[-770,-458],[-325,-53],[-505,633]],[[-752,-805],[349,776],[-799,687]],[[323,5],[561,-36],[919,-560]],[[-907,358],[264,320],[204,274]],[[-728,-466],[350,969],[292,-345]],[[940,836],[272,-533],[748,185]],[[411,998],[813,520],[316,-949]],[[-152,326],[658,-762],[148,-651]],[[330,507],[-9,-628],[101,174]],[[551,-496],[772,-541],[-702,-45]],[[-164,-489],[-90,322],[631,-59]],[[673,366],[-4,-143],[-606,-704]],[[428,-609],[801,-449],[740,-269]],[[453,-924],[-785,-346],[-853,111]],[[-738,555],[-181,467],[-426,-20]],[[958,-692],[784,-343],[505,-569]],[[620,27],[263,54],[-439,-726]],[[804,87],[998,859],[871,-78]],[[-119,-453],[-709,-292],[-115,-56]],[[-626,138],[-940,-476],[-177,-274]],[[-11,160],[142,588],[446,158]],[[538,727],[550,787],[330,810]],[[420,-689],[854,-546],[337,516]],[[872,-998],[-607,748],[473,-192]],[[653,440],[-516,-985],[808,-857]],[[374,-158],[331,-940],[-338,-641]],[[137,-925],[-179,771],[734,-715]],[[-314,198],[-115,29],[-641,-39]],[[759,-574],[-385,355],[590,-603]],[[-189,-63],[-168,204],[289,305]],[[-182,-524],[-715,-621],[911,-255]],[[331,-816],[-833,471],[168,126]],[[-514,581],[-855,-220],[-731,-507]],[[129,169],[576,651],[-87,-458]],[[783,-444],[-881,658],[-266,298]],[[603,-430],[-598,585],[368,899]],[[43,-724],[962,-376],[851,409]],[[-610,-646],[-883,-261],[-482,-881]],[[-117,-237],[978,641],[101,-747]],[[579,125],[-715,-712],[208,534]],[[672,-214],[-762,372],[874,533]],[[-564,965],[38,715],[367,242]],[[500,951],[-700,-981],[-61,-178]],[[-382,-224],[-959,903],[-282,-60]],[[-355,295],[426,-331],[-591,655]],[[892,128],[958,-271],[-993,274]],[[-454,-619],[302,138],[-790,-874]],[[-642,601],[-574,159],[-290,-318]],[[266,-109],[257,-686],[54,975]],[[162,628],[-478,840],[264,-266]],[[466,-280],[982,1],[904,-810]],[[721,839],[730,-807],[777,981]],[[-129,-430],[748,263],[943,96]],[[434,-94],[410,-990],[249,-704]],[[237,42],[122,-732],[44,-51]],[[909,-116],[-229,545],[292,717]],[[824,-768],[-807,-370],[-262,30]],[[675,58],[332,-890],[-651,791]],[[363,825],[-717,254],[684,240]],[[405,-715],[900,166],[-589,422]],[[-476,686],[-830,-319],[634,-807]],[[633,837],[-971,917],[-764,207]],[[-116,-44],[-193,-70],[908,809]],[[-26,-252],[998,408],[70,-713]],[[-601,645],[-462,842],[-644,-591]],[[-160,653],[274,113],[-138,687]],[[369,-273],[-181,925],[-167,-693]],[[-338,135],[480,-967],[-13,-840]],[[-90,-270],[-564,695],[161,907]],[[607,-430],[869,-713],[461,-469]],[[919,-165],[-776,522],[606,-708]],[[-203,465],[288,207],[-339,-458]],[[-453,-534],[-715,975],[838,-677]],[[-973,310],[-350,934],[546,-805]],[[-835,385],[708,-337],[-594,-772]],[[-14,914],[900,-495],[-627,594]],[[833,-713],[-213,578],[-296,699]],[[-27,-748],[484,455],[915,291]],[[270,889],[739,-57],[442,-516]],[[119,811],[-679,905],[184,130]],[[-678,-469],[925,553],[612,482]],[[101,-571],[-732,-842],[644,588]],[[-71,-737],[566,616],[957,-663]],[[-634,-356],[90,-207],[936,622]],[[598,443],[964,-895],[-58,529]],[[847,-467],[929,-742],[91,10]],[[-633,829],[-780,-408],[222,-30]],[[-818,57],[275,-38],[-746,198]],[[-722,-825],[-549,597],[-391,99]],[[-570,908],[430,873],[-103,-360]],[[342,-681],[512,434],[542,-528]],[[297,850],[479,609],[543,-357]],[[9,784],[212,548],[56,859]],[[-152,560],[-240,-969],[-18,713]],[[140,-133],[34,-635],[250,-163]],[[-272,-22],[-169,-662],[989,-604]],[[471,-765],[355,633],[-742,-118]],[[-118,146],[942,663],[547,-376]],[[583,16],[162,264],[715,-33]],[[-230,-446],[997,-838],[561,555]],[[372,397],[-729,-318],[-276,649]],[[92,982],[-970,-390],[-922,922]],[[-981,713],[-951,-337],[-669,670]],[[-999,846],[-831,-504],[7,-128]],[[455,-954],[-370,682],[-510,45]],[[822,-960],[-892,-385],[-662,314]],[[-668,-686],[-3 | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## --seed-contents--
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | function triangleContainment(triangles) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const testTriangles1 = [ | 
					
						
							|  |  |  |   [[-866,121],[-928,358],[459,-843]],[[-568,-631],[-352,-580],[-349,189]],[[-737,849],[-963,-486],[-662,970]],[[135,334],[-967,-71],[-365,-792]],[[789,21],[-227,51],[990,-275]],[[240,412],[-886,230],[591,256]],[[-609,472],[-853,-754],[959,661]],[[401,521],[521,314],[929,982]],[[-499,784],[-208,71],[-302,296]],[[-557,-948],[-553,-526],[-864,793]],[[270,-626],[828,44],[37,14]],[[-412,224],[617,-593],[502,699]],[[41,-908],[81,562],[-849,163]],[[165,917],[761,-197],[331,-341]],[[-687,314],[799,755],[-969,648]],[[-164,25],[578,439],[-334,-576]],[[213,535],[874,-177],[-551,24]],[[-689,291],[-795,-225],[-496,-125]],[[465,461],[558,-118],[-568,-909]],[[567,660],[-810,46],[-485,878]],[[-147,606],[685,-690],[-774,984]],[[568,-886],[-43,854],[-738,616]],[[-800,386],[-614,585],[764,-226]],[[-518,23],[-225,-732],[-79,440]],[[-173,-291],[-689,636],[642,-447]],[[-598,-16],[227,410],[496,211]],[[-474,-930],[-656,-321],[-420,36]],[[-435,165],[-819,555],[540,144]],[[-969,149],[828,568],[394,648]],[[65,-848],[257,720],[-625,-851]],[[981,899],[275,635],[465,-877]],[[80,290],[792,760],[-191,-321]],[[-605,-858],[594,33],[706,593]],[[585,-472],[318,-35],[354,-927]],[[-365,664],[803,581],[-965,-814]],[[-427,-238],[-480,146],[-55,-606]],[[879,-193],[250,-890],[336,117]],[[-226,-322],[-286,-765],[-836,-218]],[[-913,564],[-667,-698],[937,283]],[[872,-901],[810,-623],[-52,-709]],[[473,171],[717,38],[-429,-644]],[[225,824],[-219,-475],[-180,234]],[[-530,-797],[-948,238],[851,-623]],[[85,975],[-363,529],[598,28]],[[-799,166],[-804,210],[-769,851]],[[-687,-158],[885,736],[-381,-461]],[[447,592],[928,-514],[-515,-661]],[[-399,-777],[-493,80],[-544,-78]],[[-884,631],[171,-825],[-333,551]],[[191,268],[-577,676],[137,-33]],[[212,-853],[709,798],[583,-56]],[[-908,-172],[-540,-84],[-135,-56]],[[303,311],[406,-360],[-240,811]],[[798,-708],[824,59],[234,-57]],[[491,693],[-74,585],[-85,877]],[[509,-65],[-936,329],[-51,722]],[[-122,858],[-52,467],[-77,-609]],[[850,760],[547,-495],[-953,-952]],[[-460,-541],[890,910],[286,724]],[[-914,843],[-579,-983],[-387,-460]],[[989,-171],[-877,-326],[-899,458]],[[846,175],[-915,540],[-1000,-982]],[[-852,-920],[-306,496],[530,-18]],[[338,-991],[160,85],[-455,-661]],[[-186,-311],[-460,-563],[-231,-414]],[[-932,-302],[959,597],[793,748]],[[-366,-402],[-788,-279],[514,53]],[[-940,-956],[447,-956],[211,-285]],[[564,806],[-911,-914],[934,754]],[[575,-858],[-277,15],[409,-714]] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | triangleContainment(testTriangles1); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # --solutions--
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | function triangleContainment(triangles) { | 
					
						
							|  |  |  |   function isInTriangle(triangle, point) { | 
					
						
							|  |  |  |     // Based on https://stackoverflow.com/a/14382692 | 
					
						
							|  |  |  |     const area = triangleArea(triangle); | 
					
						
							|  |  |  |     const s = getS(area, point, triangle); | 
					
						
							|  |  |  |     const t = getT(area, point, triangle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s > 0 && t > 0 && 1 - s - t > 0) { | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function getS(area, point, triangle) { | 
					
						
							|  |  |  |     return ( | 
					
						
							|  |  |  |       (1 / (2 * area)) * | 
					
						
							|  |  |  |       (triangle.A.y * triangle.C.x - | 
					
						
							|  |  |  |         triangle.A.x * triangle.C.y + | 
					
						
							|  |  |  |         point.x * (triangle.C.y - triangle.A.y) + | 
					
						
							|  |  |  |         point.y * (triangle.A.x - triangle.C.x)) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function getT(area, point, triangle) { | 
					
						
							|  |  |  |     return ( | 
					
						
							|  |  |  |       (1 / (2 * area)) * | 
					
						
							|  |  |  |       (triangle.A.x * triangle.B.y - | 
					
						
							|  |  |  |         triangle.A.y * triangle.B.x + | 
					
						
							|  |  |  |         point.x * (triangle.A.y - triangle.B.y) + | 
					
						
							|  |  |  |         point.y * (triangle.B.x - triangle.A.x)) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function triangleArea(triangle) { | 
					
						
							|  |  |  |     return ( | 
					
						
							|  |  |  |       0.5 * | 
					
						
							|  |  |  |       (-triangle.B.y * triangle.C.x + | 
					
						
							|  |  |  |         triangle.A.y * (-triangle.B.x + triangle.C.x) + | 
					
						
							|  |  |  |         triangle.A.x * (triangle.B.y - triangle.C.y) + | 
					
						
							|  |  |  |         triangle.B.x * triangle.C.y) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function parseTriangle(triangle) { | 
					
						
							|  |  |  |     const points = []; | 
					
						
							|  |  |  |     for (let i = 0; i < triangle.length; i++) { | 
					
						
							|  |  |  |       const [coordinateX, coordinateY] = triangle[i]; | 
					
						
							|  |  |  |       points.push({ x: coordinateX, y: coordinateY }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const [pointA, pointB, pointC] = points; | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       A: pointA, | 
					
						
							|  |  |  |       B: pointB, | 
					
						
							|  |  |  |       C: pointC | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const origin = { x: 0, y: 0 }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   let trianglesInside = 0; | 
					
						
							|  |  |  |   for (let i = 0; i < triangles.length; i++) { | 
					
						
							|  |  |  |     const triangle = parseTriangle(triangles[i]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (isInTriangle(triangle, origin)) { | 
					
						
							|  |  |  |       trianglesInside++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return trianglesInside; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` |