package day14

import (
	_ "adventofcode2023/utils"
	"adventofcode2023/utils/grid2d"
	"adventofcode2023/utils/inputs"
	"fmt"
	_ "strings"
)

func Part1(input string) int {
	grid := inputs.ToGrid2D[rune](input, "\n", "", ' ', func(c string) rune { return rune(c[0])})
//	fmt.Println(grid.StringWithFormatter(func(c rune, x int, y int) string { return string(c)}))
	slide(grid)
//	fmt.Println(grid.StringWithFormatter(func(c rune, x int, y int) string { return string(c)}))
	return score(grid)
}

func Part2(input string) int {
	grid := inputs.ToGrid2D[rune](input, "\n", "", ' ', func(c string) rune { return rune(c[0])})
//	fmt.Println(grid.StringWithFormatter(func(c rune, x int, y int) string { return string(c)}))
	x:= 0
	for j:=0;j<125;j++ {
		for i:=0;i<4;i++ {
			slide(grid)
			grid = rotate(grid)
		}
		if  score(grid) == 101375 { 
			fmt.Println(j, j - x)
			x = j
		 }
	}
	fmt.Println(score(grid))
	for j:=999999840+125;j<1000000000;j++ {
		for i:=0;i<4;i++ {
			slide(grid)
			grid = rotate(grid)
		}
		if  score(grid) == 101375 { 
			fmt.Println(j, j - x)
			x = j
		 }
	}
//	fmt.Println(grid.StringWithFormatter(func(c rune, x int, y int) string { return string(c)}))
	return score(grid)
}


func slide(grid *grid2d.Grid[rune]) {
	G := grid.Matrix()
	R := len(G)
	C := len(G[0])
	for c:=0;c<C;c++ {
		for r:=0;r<R;r++ {
			for dr:=0;dr<R;dr++ {
				if G[dr][c]=='O' && dr>0 && G[dr-1][c]=='.' {
					G[dr][c]='.'
					G[dr-1][c] = 'O'
				}
			}
		}
	}

}

func rotate(grid *grid2d.Grid[rune]) *grid2d.Grid[rune] {
	G := grid.Matrix()
	R := len(G)
	C := len(G[0])
	New := grid2d.NewGrid[rune](R, C, '?')
	NG := New.Matrix()
	for r:=0;r<R;r++ {
    	for c:=0;c<C;c++ {
      		NG[c][R-1-r] = G[r][c]
		}
	}
  	return New
}

func score(grid *grid2d.Grid[rune]) int {
	ans := 0

	G := grid.Matrix()
	R := len(G)
	C := len(G[0])

  	for r:=0;r<R;r++ {
    	for c:=0;c<C;c++ {
    		if G[r][c]=='O' {
        		ans += len(G)-r
	  		}
		}
	}
  	return ans
}