package cz.wrent.advent

fun main() {
	println(partOne(test))

	val result = partOne(input)
	println("8a: $result")

	println(partTwo(test))
	val resultTwo = partTwo(input)
	println("8b: $resultTwo")
}

private fun partOne(input: String): Long {
	val map = input.parse()
	val visible = mutableSetOf<Pair<Int, Int>>()

	processDirectionFromZero(map, visible)
	processDirectionFromZero(map, visible, true)
	processDirectionToZero(map, visible)
	processDirectionToZero(map, visible, true)
	return visible.size.toLong()
}

private fun partTwo(input: String): Long {
	val map = input.parse()

	val scenicMap = map.map { it.key to getScenicScore(it.key, map) }.toMap()
	println(scenicMap)
	return scenicMap.values.maxByOrNull { it }!!.toLong()
}

private fun getScenicScore(coord: Pair<Int, Int>, map: Map<Pair<Int, Int>, Int>): Int {
	val current = map[coord]!!
	val a = map.getRightFrom(coord).getVisible(current)
	val b = map.getLeftFrom(coord).getVisible(current)
	val c = map.getUpFrom(coord).getVisible(current)
	val d = map.getDownFrom(coord).getVisible(current)
	return a * b * c * d
}

private fun List<Int>.getVisible(current: Int): Int {
	val res = this.takeWhile{ it < current }.size

	if (res == this.size) {
		return res
	} else {
		return res + 1
	}
}

private fun Map<Pair<Int, Int>, Int>.getRightFrom(coord: Pair<Int, Int>): List<Int> {
	return this.filter { it.key.second == coord.second }
		.filter { it.key.first > coord.first }.entries.sortedBy { it.key.first }.map { it.value }.toList()
}

private fun Map<Pair<Int, Int>, Int>.getLeftFrom(coord: Pair<Int, Int>): List<Int> {
	return this.filter { it.key.second == coord.second }
		.filter { it.key.first < coord.first }.entries.sortedByDescending { it.key.first }.map { it.value }.toList()
}

private fun Map<Pair<Int, Int>, Int>.getUpFrom(coord: Pair<Int, Int>): List<Int> {
	return this.filter { it.key.first == coord.first }
		.filter { it.key.second < coord.second }.entries.sortedByDescending { it.key.second }.map { it.value }.toList()
}

private fun Map<Pair<Int, Int>, Int>.getDownFrom(coord: Pair<Int, Int>): List<Int> {
	return this.filter { it.key.first == coord.first }
		.filter { it.key.second > coord.second }.entries.sortedBy { it.key.second }.map { it.value }.toList()
}

private fun processDirectionFromZero(
	map: Map<Pair<Int, Int>, Int>,
	visible: MutableSet<Pair<Int, Int>>,
	switch: Boolean = false
) {
	val max = map.keys.maxByOrNull { it.first }!!.first
	var i = 0
	var j = 0
	var localMax = -1
	while (j <= max) {
		while (i <= max) {
			val coord = if (switch) j to i else i to j
			val current = map[coord] ?: break
			if (current > localMax) {
				visible.add(coord)
				localMax = current
			}
			i++
		}
		localMax = -1
		i = 0
		j++
	}
}

private fun processDirectionToZero(
	map: Map<Pair<Int, Int>, Int>,
	visible: MutableSet<Pair<Int, Int>>,
	switch: Boolean = false
) {
	val max = map.keys.maxByOrNull { it.first }!!.first
	var i = max
	var j = max
	var localMax = -1
	while (j >= 0) {
		while (i >= 0) {
			val coord = if (switch) j to i else i to j
			val current = map[coord] ?: break
			if (current > localMax) {
				visible.add(coord)
				localMax = current
			}
			i--
		}
		localMax = -1
		i = max
		j--
	}
}

private fun String.parse(): Map<Pair<Int, Int>, Int> {
	val map = mutableMapOf<Pair<Int, Int>, Int>()
	this.split("\n")
		.mapIndexed { i, row ->
			row.split("").filter { it.isNotEmpty() }.forEachIndexed { j, value ->
				map.put(j to i, value.toInt())
			}
		}
	return map
}

private const val test = """30373
25512
65332
33549
35390"""

private const val input =
	"""003112220410413101104044022234320204233341435252223642044225451531421012104343030211442433410302111
301233004003313130222434121135033231250505241131342032404032560542233000343455552123100410402211201
111301041221333142533352050250154136146324550411565615444115604102531135302000320033233340431313123
011312210420442043155233305201305643445224334303310253225205601265233454400214114322131420224022313
130102441231200141254202121022423405224443210463250415204410624313613034320040015223211432442333110
133121132322223054104323242043651144066341346000104210124535555236324451132555525220523220023202433
110011123024113203143145243605143331512223606564503661350336662505131254503242354031400131012444222
221400422202335053520044325014041432662161415523526711633662600635304000112322014001533351130303321
030222020044115331004065013253364503664435753416641653716424535324654054023321025154331103034342414
030331241153233040140314112524504535172167445223426653152774166352145410064425434012002122431142343
224111232453145423354550035141103644127571711431336236226321752314754510214316215104550522141301020
424321022432003551434012134531644165753146143232242275633762323631713541330463531053004424012234010
221233440041435131321565604060121637542135243721227576264551457171313165211546132314103242442012133
301320232222024200651041405631257577625236256225367443317773421262762172454463051224654015452230401
124314451244222611016300517414362722551374735555353871173242751564427674344212032442221554524035432
000210412345203005364660077252742673773341654558568632445755573574757433452636410261362004114032013
333130514223252440150314572132443233363783556666363566733363262631651361523573335361463232143300044
400403124212626240015541437753711632635435857234865883574647337436376563235264524230225211320425534
430312520241033613150127256341412352564548243842255622454762832274857163157242366022041262252034150
125211521340246341461723355443362487532437274863758283488567453538667642367654751321503343220351304
015045453331430626273664314125778234645658386774837783464366334264476243327176571544650404453253132
354034323663213666746174754737374552772744668787244468236435632534753452366177147233020313054042345
305241054630156250416544221136444247327848337737584777837244467756426322644474332262330430251551212
100144030632532041231474166555527386344645548655948476835366757558682728623657547471260405014131510
155501551351164622444476154658383338677369856795967346765977585753438378656352723127554031451225340
213252046404053134327512554784653544697439375473948735593644477348334755453317243676612665133404310
022440140420166534174335264388542568833984445757393864997986883894574577853347367415453352646352541
303425632364032563633467847288735478557676734393879573848466463466672455482853676764477400452414425
421140260266576264621526686828328833799894373434775335763857585383998562862724435337211515426106224
251234063153345361761483764445395779384568938899876568577359785776678952473247274437226445141011143
124165362100637756715727365876646574835535677777467785479666667584536895483528343623556220650044411
523533116461715454347526758528694839737349689796485884675949699354664766465728468324363766204426020
011655232111314171647378426863359767797699886798595874554677869353593448485338287251255363024600501
201454444103773472628888556987787587788889498545597569965587748496753787964648276727241677205552530
022050015673621733475438774338498584975649879876857968775687577968447843939528275674512475556245535
415145246426622536566872225778388854879897849855475687687595454675468637795674534385355242230005213
515410462156777244275234668693874665788796767699675757959578987749863457937753862877526274731341533
532441044352764132482273798897585496755464759898898996955476545867443535986538526852746625533463346
042116466642255478273735578633656564997786577695957789988869999965866866547392358543326526744105124
305463642721567264236826357995536786844968968785757997557699474697669835738584868845834527260231552
066231251534151145564875937345768799895756579656987695996797768779596848379994862646436522463360266
506513057363414584637639439854956668854878865987777598756576697549657897644947484484534264535522136
131666244551736787837659743739478747677995596779697659755568679946768553647438363837764527562663652
424404413335566473356634745356959967996577965786978695878778775749964899347635788855331715645156443
366410447316422733452686338845457787759555776998978979667795556665499755678449775626855353212651324
302136251253517685366593955978666557656668675898896669776695986549696689467499828826265743355612425
546506521534743584874443398869667685788797956777788696997955989646664668879679457843885333126334344
362262154313747445367249673496655464765879658679769897687679766789496785648597346877862642316202103
026226125354532563527338467655476495659657769687899897897899856576869585587683926347427571714351012
324246031677535478765836973778855888768885696676889798687785885666785975868394627754287365751563132
031351623136767474878299634934847976977866799698978866969865695657475657893553946224747277645245120
026056143144572747422538333594694756756655696798979976879958687957995676939686658475475623336500612
662533125413523284737634669357979456995895856799797767679899585888899799675553357648455413641663031
014206153225663545455694774965848955686699676678777689996997596965668976646983688667633463335404141
413012617325174456878669973969459678955956597997687976869576778966464554568469886777721516427616513
502662203642612255238447486939957458967857897679766997696655868558575999589335922456844736112131654
212661502516734223324889447354689969855787756889968698877896757975877697383989627364337421772343024
062105566125733258245733457473775547779958796868868895787767755559647545379345865238624356123242000
402335614754636628236824679555597465548989986755969565969678898559987586856955673832271674166105362
451334645753376162243335579543677879955598768556565759756869877876795947966569855573232735534601241
500262052615557247375888358635954578969966856685689678868986899965887995757987425824514566556143415
025221464647151347477323745438738647477798995699788989796688598687779795846437577837865212462025305
506261641542645445623578634938859695857548567987658895685668887664467397754563764284864222243613255
544001251632514343434242438697698767785468785559797877757559476976744589553445545348132556324315401
312662335054751647576346847944998349986995969646958568675577475645539379875732364426714676752004534
442336642122316123757636234859863735657746598877646757975758669549947438746824526434264347133600103
110222605363451462773826376864836593598856459788567868745977445869448964569655348846536363204056350
000101232124176476234372634789857987399659768658796566947966644948468844584756623732364133065443412
134465433226374477324823357757785535937975665949586889647565456766846389552458234767667646466124353
421406224300535763513347544755878674693949665984559799965894778876384773264625738631365460212615513
452351220036426717772576544574486575445936589965659469684553983864958887588836456352652752044465624
513131310021516677236857346343788436737376979889979498674877368855367664436225742117611411543534241
025341550553445563557374338552585545787433393754685485676457956894674542662544752536711135543323540
535152616216423251726174753447757785566344854848638858756838495369785886445488572266324260520452211
040010242452167571763413223445374499838658479769797468459895353937866635767567612446231533425561512
540233435611063354343623584674548775576735445736954663985773597646587532834332126771664204465150223
115125460640513624264577427672484376565394997956949478368583668555354324253116433334364541633501141
325235035031330065764773672233563447278366899833655673943396323666327273534372213517324021336301134
210455052102126060367721574443448283734742249765698995536842573866568587565571317173455040136014133
130303041444343616551636147765524538863657233824485633222587838375574238775244261440413305250410213
215411311040450233266672334763832288583822422248882386376826865647256855122326112462046245434214110
230231555011111141243461222762213386584878775753548542777758687642766773174237314624160241043301041
323544455001621231632772663352437368846236258422868628887825466644733647626344222306513541033345051
103143140115330535101443674523313247636278477357763543634765673375252223123145511514215131041302240
232425305344242122243634141575125456216884578682284677823883878251534364736772005201664151453532422
102015414143426060302001452111353522415644252842283555326642135161755673127454553246636405351210230
434225550123100466121402111553624464277266354226553673463535217337233242261322143516321221202244233
241043514014314144343662453056766274716234347315115145214653247673432611160552306341450310405413111
242112143335044304622645260260424573275613637141734623226773527441742321265241643455134145215344111
111301110035433343532532505066367716542154757534155161173124736561116131435620565213531350550432142
242323242143224035106205224411500635634124323342513747342475634262646442514656422055112331122023144
002021344233114150010341663531513334522142253265466242366366534525551142525131661102314124401314042
024004104024242151413420354625126365606642452553232242411563750634302214411623615524332515123123121
322320201030004104054100060453523451362415465573527326430616603635233444523531105134335533102202414
013231044323002420215041311645066036204353535300445225661352044506065120312154410321400034312200320
031030413344440552442114452066553136026033443442226333515665300213012326102141034413121232242040400
133131302014414220215344004521556454235620502443013233464014064103264525100404050140223431001414000
221120341111243124154321401255010441026151433422443520262166251632146441120442553301443334201231200
021222222103332103301112520131442023663055232552042262505152050120510455441325453404132240001402111"""

package cz.wrent.advent

fun main() {
	println(partOne(test))

	val result = partOne(input)
	println("8a: $result")

	println(partTwo(test))
	val resultTwo = partTwo(input)
	println("8b: $resultTwo")
}

private fun partOne(input: String): Long {
	val map = input.parse()
	val visible = mutableSetOf<Pair<Int, Int>>()

	processDirectionFromZero(map, visible)
	processDirectionFromZero(map, visible, true)
	processDirectionToZero(map, visible)
	processDirectionToZero(map, visible, true)
	return visible.size.toLong()
}

private fun partTwo(input: String): Long {
	val map = input.parse()

	val scenicMap = map.map { it.key to getScenicScore(it.key, map) }.toMap()
	println(scenicMap)
	return scenicMap.values.maxByOrNull { it }!!.toLong()
}

private fun getScenicScore(coord: Pair<Int, Int>, map: Map<Pair<Int, Int>, Int>): Int {
	val current = map[coord]!!
	val a = map.getRightFrom(coord).getVisible(current)
	val b = map.getLeftFrom(coord).getVisible(current)
	val c = map.getUpFrom(coord).getVisible(current)
	val d = map.getDownFrom(coord).getVisible(current)
	return a * b * c * d
}

private fun List<Int>.getVisible(current: Int): Int {
	val res = this.takeWhile{ it < current }.size

	if (res == this.size) {
		return res
	} else {
		return res + 1
	}
}

private fun Map<Pair<Int, Int>, Int>.getRightFrom(coord: Pair<Int, Int>): List<Int> {
	return this.filter { it.key.second == coord.second }
		.filter { it.key.first > coord.first }.entries.sortedBy { it.key.first }.map { it.value }.toList()
}

private fun Map<Pair<Int, Int>, Int>.getLeftFrom(coord: Pair<Int, Int>): List<Int> {
	return this.filter { it.key.second == coord.second }
		.filter { it.key.first < coord.first }.entries.sortedByDescending { it.key.first }.map { it.value }.toList()
}

private fun Map<Pair<Int, Int>, Int>.getUpFrom(coord: Pair<Int, Int>): List<Int> {
	return this.filter { it.key.first == coord.first }
		.filter { it.key.second < coord.second }.entries.sortedByDescending { it.key.second }.map { it.value }.toList()
}

private fun Map<Pair<Int, Int>, Int>.getDownFrom(coord: Pair<Int, Int>): List<Int> {
	return this.filter { it.key.first == coord.first }
		.filter { it.key.second > coord.second }.entries.sortedBy { it.key.second }.map { it.value }.toList()
}

private fun processDirectionFromZero(
	map: Map<Pair<Int, Int>, Int>,
	visible: MutableSet<Pair<Int, Int>>,
	switch: Boolean = false
) {
	val max = map.keys.maxByOrNull { it.first }!!.first
	var i = 0
	var j = 0
	var localMax = -1
	while (j <= max) {
		while (i <= max) {
			val coord = if (switch) j to i else i to j
			val current = map[coord] ?: break
			if (current > localMax) {
				visible.add(coord)
				localMax = current
			}
			i++
		}
		localMax = -1
		i = 0
		j++
	}
}

private fun processDirectionToZero(
	map: Map<Pair<Int, Int>, Int>,
	visible: MutableSet<Pair<Int, Int>>,
	switch: Boolean = false
) {
	val max = map.keys.maxByOrNull { it.first }!!.first
	var i = max
	var j = max
	var localMax = -1
	while (j >= 0) {
		while (i >= 0) {
			val coord = if (switch) j to i else i to j
			val current = map[coord] ?: break
			if (current > localMax) {
				visible.add(coord)
				localMax = current
			}
			i--
		}
		localMax = -1
		i = max
		j--
	}
}

private fun String.parse(): Map<Pair<Int, Int>, Int> {
	val map = mutableMapOf<Pair<Int, Int>, Int>()
	this.split("\n")
		.mapIndexed { i, row ->
			row.split("").filter { it.isNotEmpty() }.forEachIndexed { j, value ->
				map.put(j to i, value.toInt())
			}
		}
	return map
}

private const val test = """30373
25512
65332
33549
35390"""

private const val input =
	"""003112220410413101104044022234320204233341435252223642044225451531421012104343030211442433410302111
301233004003313130222434121135033231250505241131342032404032560542233000343455552123100410402211201
111301041221333142533352050250154136146324550411565615444115604102531135302000320033233340431313123
011312210420442043155233305201305643445224334303310253225205601265233454400214114322131420224022313
130102441231200141254202121022423405224443210463250415204410624313613034320040015223211432442333110
133121132322223054104323242043651144066341346000104210124535555236324451132555525220523220023202433
110011123024113203143145243605143331512223606564503661350336662505131254503242354031400131012444222
221400422202335053520044325014041432662161415523526711633662600635304000112322014001533351130303321
030222020044115331004065013253364503664435753416641653716424535324654054023321025154331103034342414
030331241153233040140314112524504535172167445223426653152774166352145410064425434012002122431142343
224111232453145423354550035141103644127571711431336236226321752314754510214316215104550522141301020
424321022432003551434012134531644165753146143232242275633762323631713541330463531053004424012234010
221233440041435131321565604060121637542135243721227576264551457171313165211546132314103242442012133
301320232222024200651041405631257577625236256225367443317773421262762172454463051224654015452230401
124314451244222611016300517414362722551374735555353871173242751564427674344212032442221554524035432
000210412345203005364660077252742673773341654558568632445755573574757433452636410261362004114032013
333130514223252440150314572132443233363783556666363566733363262631651361523573335361463232143300044
400403124212626240015541437753711632635435857234865883574647337436376563235264524230225211320425534
430312520241033613150127256341412352564548243842255622454762832274857163157242366022041262252034150
125211521340246341461723355443362487532437274863758283488567453538667642367654751321503343220351304
015045453331430626273664314125778234645658386774837783464366334264476243327176571544650404453253132
354034323663213666746174754737374552772744668787244468236435632534753452366177147233020313054042345
305241054630156250416544221136444247327848337737584777837244467756426322644474332262330430251551212
100144030632532041231474166555527386344645548655948476835366757558682728623657547471260405014131510
155501551351164622444476154658383338677369856795967346765977585753438378656352723127554031451225340
213252046404053134327512554784653544697439375473948735593644477348334755453317243676612665133404310
022440140420166534174335264388542568833984445757393864997986883894574577853347367415453352646352541
303425632364032563633467847288735478557676734393879573848466463466672455482853676764477400452414425
421140260266576264621526686828328833799894373434775335763857585383998562862724435337211515426106224
251234063153345361761483764445395779384568938899876568577359785776678952473247274437226445141011143
124165362100637756715727365876646574835535677777467785479666667584536895483528343623556220650044411
523533116461715454347526758528694839737349689796485884675949699354664766465728468324363766204426020
011655232111314171647378426863359767797699886798595874554677869353593448485338287251255363024600501
201454444103773472628888556987787587788889498545597569965587748496753787964648276727241677205552530
022050015673621733475438774338498584975649879876857968775687577968447843939528275674512475556245535
415145246426622536566872225778388854879897849855475687687595454675468637795674534385355242230005213
515410462156777244275234668693874665788796767699675757959578987749863457937753862877526274731341533
532441044352764132482273798897585496755464759898898996955476545867443535986538526852746625533463346
042116466642255478273735578633656564997786577695957789988869999965866866547392358543326526744105124
305463642721567264236826357995536786844968968785757997557699474697669835738584868845834527260231552
066231251534151145564875937345768799895756579656987695996797768779596848379994862646436522463360266
506513057363414584637639439854956668854878865987777598756576697549657897644947484484534264535522136
131666244551736787837659743739478747677995596779697659755568679946768553647438363837764527562663652
424404413335566473356634745356959967996577965786978695878778775749964899347635788855331715645156443
366410447316422733452686338845457787759555776998978979667795556665499755678449775626855353212651324
302136251253517685366593955978666557656668675898896669776695986549696689467499828826265743355612425
546506521534743584874443398869667685788797956777788696997955989646664668879679457843885333126334344
362262154313747445367249673496655464765879658679769897687679766789496785648597346877862642316202103
026226125354532563527338467655476495659657769687899897897899856576869585587683926347427571714351012
324246031677535478765836973778855888768885696676889798687785885666785975868394627754287365751563132
031351623136767474878299634934847976977866799698978866969865695657475657893553946224747277645245120
026056143144572747422538333594694756756655696798979976879958687957995676939686658475475623336500612
662533125413523284737634669357979456995895856799797767679899585888899799675553357648455413641663031
014206153225663545455694774965848955686699676678777689996997596965668976646983688667633463335404141
413012617325174456878669973969459678955956597997687976869576778966464554568469886777721516427616513
502662203642612255238447486939957458967857897679766997696655868558575999589335922456844736112131654
212661502516734223324889447354689969855787756889968698877896757975877697383989627364337421772343024
062105566125733258245733457473775547779958796868868895787767755559647545379345865238624356123242000
402335614754636628236824679555597465548989986755969565969678898559987586856955673832271674166105362
451334645753376162243335579543677879955598768556565759756869877876795947966569855573232735534601241
500262052615557247375888358635954578969966856685689678868986899965887995757987425824514566556143415
025221464647151347477323745438738647477798995699788989796688598687779795846437577837865212462025305
506261641542645445623578634938859695857548567987658895685668887664467397754563764284864222243613255
544001251632514343434242438697698767785468785559797877757559476976744589553445545348132556324315401
312662335054751647576346847944998349986995969646958568675577475645539379875732364426714676752004534
442336642122316123757636234859863735657746598877646757975758669549947438746824526434264347133600103
110222605363451462773826376864836593598856459788567868745977445869448964569655348846536363204056350
000101232124176476234372634789857987399659768658796566947966644948468844584756623732364133065443412
134465433226374477324823357757785535937975665949586889647565456766846389552458234767667646466124353
421406224300535763513347544755878674693949665984559799965894778876384773264625738631365460212615513
452351220036426717772576544574486575445936589965659469684553983864958887588836456352652752044465624
513131310021516677236857346343788436737376979889979498674877368855367664436225742117611411543534241
025341550553445563557374338552585545787433393754685485676457956894674542662544752536711135543323540
535152616216423251726174753447757785566344854848638858756838495369785886445488572266324260520452211
040010242452167571763413223445374499838658479769797468459895353937866635767567612446231533425561512
540233435611063354343623584674548775576735445736954663985773597646587532834332126771664204465150223
115125460640513624264577427672484376565394997956949478368583668555354324253116433334364541633501141
325235035031330065764773672233563447278366899833655673943396323666327273534372213517324021336301134
210455052102126060367721574443448283734742249765698995536842573866568587565571317173455040136014133
130303041444343616551636147765524538863657233824485633222587838375574238775244261440413305250410213
215411311040450233266672334763832288583822422248882386376826865647256855122326112462046245434214110
230231555011111141243461222762213386584878775753548542777758687642766773174237314624160241043301041
323544455001621231632772663352437368846236258422868628887825466644733647626344222306513541033345051
103143140115330535101443674523313247636278477357763543634765673375252223123145511514215131041302240
232425305344242122243634141575125456216884578682284677823883878251534364736772005201664151453532422
102015414143426060302001452111353522415644252842283555326642135161755673127454553246636405351210230
434225550123100466121402111553624464277266354226553673463535217337233242261322143516321221202244233
241043514014314144343662453056766274716234347315115145214653247673432611160552306341450310405413111
242112143335044304622645260260424573275613637141734623226773527441742321265241643455134145215344111
111301110035433343532532505066367716542154757534155161173124736561116131435620565213531350550432142
242323242143224035106205224411500635634124323342513747342475634262646442514656422055112331122023144
002021344233114150010341663531513334522142253265466242366366534525551142525131661102314124401314042
024004104024242151413420354625126365606642452553232242411563750634302214411623615524332515123123121
322320201030004104054100060453523451362415465573527326430616603635233444523531105134335533102202414
013231044323002420215041311645066036204353535300445225661352044506065120312154410321400034312200320
031030413344440552442114452066553136026033443442226333515665300213012326102141034413121232242040400
133131302014414220215344004521556454235620502443013233464014064103264525100404050140223431001414000
221120341111243124154321401255010441026151433422443520262166251632146441120442553301443334201231200
021222222103332103301112520131442023663055232552042262505152050120510455441325453404132240001402111"""
