<?php

//01-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent01Input.txt','r');
$temp = 10000;
$total = 0;
while ($line = fgets($fh)) {
    $current = intval($line);
    if($current > $temp)
        $total += 1;
    $temp = $current;
}
fclose($fh);
Log::write($total);
*/


//01-2
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent01Input.txt','r');
$tempA1 = 10000;
$tempA2 = 10000;
$tempA3 = 10000;
$tempB1 = 10000;
$tempB2 = 10000;
$tempB3 = 10000;
$total = 0;
while ($line = fgets($fh)) {
    $current = intval($line);
    $tempA1 = $tempA2;
    $tempA2 = $tempA3;
    $tempA3 = $tempB3;

    $tempB1 = $tempB2;
    $tempB2 = $tempB3;
    $tempB3 = $current;

    if($tempB1 + $tempB2 + $tempB3 > $tempA1 + $tempA2 + $tempA3)
        $total += 1;
}
fclose($fh);
Log::write($total);
*/




//02-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent02Input.txt','r');
$depth = 0;
$hori = 0;
while ($line = fgets($fh)) {
    $words = explode(" ", $line);
    if(strcmp("forward", trim($words[0])) == 0){
        $hori += intval(trim($words[1]));
    } else if (strcmp("up", trim($words[0])) == 0){
        $depth -= intval(trim($words[1]));
    } else if (strcmp("down", trim($words[0])) == 0){
        $depth += intval(trim($words[1]));
    } 
}
fclose($fh);
Log::write(($depth * $hori));*/


//02-2
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent02Input.txt','r');
$depth = 0;
$hori = 0;
$aim = 0;
while ($line = fgets($fh)) {
    $words = explode(" ", $line);
    if(strcmp("forward", trim($words[0])) == 0){
        $hori += intval(trim($words[1]));
        $depth += $aim * intval(trim($words[1]));
    } else if (strcmp("up", trim($words[0])) == 0){
        $aim -= intval(trim($words[1]));
    } else if (strcmp("down", trim($words[0])) == 0){
        $aim += intval(trim($words[1]));
    } 
}
fclose($fh);
Log::write(($depth * $hori));
*/




//03-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent03Input.txt','r');
$countZero = array();
$countOne = array();
for($i=0;$i<12;$i++){
    $countZero[$i] = 0;
    $countOne[$i] = 0;
}
while ($line = fgets($fh)) {
    for($i=0;$i<12;$i++){
        if(strcmp(substr($line, $i, 1), "1") == 0){
            $countZero[$i] += 1;
        } else {
            $countOne[$i] += 1;
        }
    }
}
Log::write($countOne);
Log::write($countZero);
$resGamma = "";
$resEpsilon = "";
for($i=0;$i<12;$i++){
    if($countZero[$i] > $countOne[$i]){
        $resGamma .= "0";
        $resEpsilon .= "1";
    } else {
        $resGamma .= "1";
        $resEpsilon .= "0";
    }
}
Log::write($resGamma . " - " . $resEpsilon);
Log::write(bindec($resGamma) . " - " . bindec($resEpsilon));
Log::write(bindec($resGamma) * bindec($resEpsilon));
fclose($fh);
*/

//03-2
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent03Input.txt','r');
$input = array();
while ($line = fgets($fh)) {
    $input[] = $line;
}
$resGamma = "";
$resEpsilon = "";
for($i=0;$i<12 && strlen($resGamma) < 12;$i++){
    $countOne = 0;
    $countZero = 0;
    $countFound = 0;
    $onlyOne = "";
    for($j=0;$j<count($input);$j++){
        if(strlen($resGamma) == 0 || strcmp(substr($input[$j],0,$i),$resGamma) == 0){
            $countFound += 1;
            $onlyOne = $input[$j];
            if(strcmp(substr($input[$j], $i, 1), "1") == 0){
                $countOne += 1;
            } else {
                $countZero += 1;
            }
        }
    }
    if($countFound == 1){
        $resGamma = $onlyOne;
    } else {
        if($countOne >= $countZero){
            $resGamma .= "1";
        } else {
            $resGamma .= "0";
        }
    }
    Log::write($i . " - " . $countZero . " - " . $countOne . " - " . $resGamma . " - " . $countFound);
}

for($i=0;$i<12 && strlen($resEpsilon) < 12;$i++){
    $countOne = 0;
    $countZero = 0;
    $countFound = 0;
    $onlyOne = "";
    for($j=0;$j<count($input);$j++){
        if(strlen($resEpsilon) == 0 || strcmp(substr($input[$j],0,$i),$resEpsilon) == 0){
            $countFound += 1;
            $onlyOne = $input[$j];
            if(strcmp(substr($input[$j], $i, 1), "1") == 0){
                $countOne += 1;
            } else {
                $countZero += 1;
            }
        }
    }
    if($countFound == 1){
        $resEpsilon = $onlyOne;
    } else {
        if($countZero <= $countOne){
            $resEpsilon .= "0";
        } else {
            $resEpsilon .= "1";
        }
    }
}

Log::write($resGamma . " - " . $resEpsilon);
Log::write(bindec($resGamma) . " - " . bindec($resEpsilon));
Log::write(bindec($resGamma) * bindec($resEpsilon));
fclose($fh);
*/




//04-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent04Input.txt','r');
$first = true;
$callOrder = array();
$bingoBoard = array();
$statusBoard = array();
while ($line = fgets($fh)) {
    if($first){
        $callOrder = explode(",", trim($line));
    } else {
        if(strlen(trim($line)) > 0){
            $board = array();
            $status = array();

            $temp = explode(" ", trim(str_replace("  ", " ", $line)));
            $board[] = $temp;
            $x = array();
            for($j=0;$j<5;$j++){
                $x[] = 0;
            }
            $status[] = $x;

            for($i=0;$i<4;$i++){
                $line = fgets($fh);
                $temp = explode(" ", trim(str_replace("  ", " ", $line)));
                $board[] = $temp;

                $x = array();
                for($j=0;$j<5;$j++){
                    $x[] = 0;
                }
                $status[] = $x;
            }

            $bingoBoard[] = $board;
            $statusBoard[] = $status;
        }
    }
    $first = false;
}
//Log::write($callOrder);
//Log::write($bingoBoard);
$found = false;
$whenIdx = -1;
$winningCall = -1;
$winBoard = null;
$statusWinBoard = null;

for($i=0;$i<count($callOrder) && !$found ;$i++){
    for($j=0;$j<count($bingoBoard) && !$found ;$j++){
        for($k=0;$k<5 && !$found ;$k++){
            for($l=0;$l<5 && !$found ;$l++){
                if(intval($bingoBoard[$j][$k][$l]) == intval($callOrder[$i])){
                    $statusBoard[$j][$k][$l] = 1;

                    //check status vertical
                    $wrongVertical = false;
                    for($a=0;$a<5 && !$wrongVertical;$a++){
                        if($statusBoard[$j][$a][$l] == 0){
                            $wrongVertical = true;
                        }
                    }

                    //check status horizontal
                    $wrongHorizontal = false;
                    for($a=0;$a<5 && !$wrongHorizontal;$a++){
                        if($statusBoard[$j][$k][$a] == 0){
                            $wrongHorizontal = true;
                        }
                    }

                    if(!$wrongHorizontal || !$wrongVertical){
                        $found = true;
                        $winBoard = $bingoBoard[$j];
                        $statusWinBoard = $statusBoard[$j];
                        $whenIdx = $i;
                        $winningCall = intval($callOrder[$i]);
                    }
                }
            }
        }
    }
}

Log::write($whenIdx);
Log::write($winBoard);
Log::write($statusWinBoard);
Log::write($winningCall);
$sumUnmarked = 0;
for($k=0;$k<5;$k++){
    for($l=0;$l<5;$l++){
        if($statusWinBoard[$k][$l] == 0){
            $sumUnmarked += intval($winBoard[$k][$l]);
        }
    }
}
Log::write($sumUnmarked);
Log::write($sumUnmarked * $winningCall);
fclose($fh);
*/

//04-2
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent04Input.txt','r');
$first = true;
$callOrder = array();
$bingoBoard = array();
$statusBoard = array();
$winOrNotBoard = array();
while ($line = fgets($fh)) {
    if($first){
        $callOrder = explode(",", trim($line));
    } else {
        if(strlen(trim($line)) > 0){
            $board = array();
            $status = array();

            $temp = explode(" ", trim(str_replace("  ", " ", $line)));
            $board[] = $temp;
            $x = array();
            for($j=0;$j<5;$j++){
                $x[] = 0;
            }
            $status[] = $x;

            for($i=0;$i<4;$i++){
                $line = fgets($fh);
                $temp = explode(" ", trim(str_replace("  ", " ", $line)));
                $board[] = $temp;

                $x = array();
                for($j=0;$j<5;$j++){
                    $x[] = 0;
                }
                $status[] = $x;
            }

            $bingoBoard[] = $board;
            $statusBoard[] = $status;
            $winOrNotBoard[] = 0;
        }
    }
    $first = false;
}
//Log::write($callOrder);
//Log::write($bingoBoard);
$finished = false;
$whenIdx = -1;
$winningCall = -1;
$winBoard = null;
$statusWinBoard = null;
$countWin = 0;

for($i=0;$i<count($callOrder) && !$finished ;$i++){
    for($j=0;$j<count($bingoBoard) && !$finished ;$j++){
        if($winOrNotBoard[$j] == 0){
            for($k=0;$k<5 && !$finished ;$k++){
                for($l=0;$l<5 && !$finished ;$l++){
                    if(intval($bingoBoard[$j][$k][$l]) == intval($callOrder[$i])){
                        $statusBoard[$j][$k][$l] = 1;
    
                        //check status vertical
                        $wrongVertical = false;
                        for($a=0;$a<5 && !$wrongVertical;$a++){
                            if($statusBoard[$j][$a][$l] == 0){
                                $wrongVertical = true;
                            }
                        }
    
                        //check status horizontal
                        $wrongHorizontal = false;
                        for($a=0;$a<5 && !$wrongHorizontal;$a++){
                            if($statusBoard[$j][$k][$a] == 0){
                                $wrongHorizontal = true;
                            }
                        }
    
                        if(!$wrongHorizontal || !$wrongVertical){
                            $winBoard = $bingoBoard[$j];
                            $statusWinBoard = $statusBoard[$j];
                            $whenIdx = $i;
                            $winningCall = intval($callOrder[$i]);

                            $countWin += 1;
                            $winOrNotBoard[$j] = 1;

                            if($countWin == count($bingoBoard)){
                                $finished = true;
                            }
                        }
                    }
                }
            }

        }
    }
}

Log::write($whenIdx);
Log::write($winBoard);
Log::write($statusWinBoard);
Log::write($winningCall);
$sumUnmarked = 0;
for($k=0;$k<5;$k++){
    for($l=0;$l<5;$l++){
        if($statusWinBoard[$k][$l] == 0){
            $sumUnmarked += intval($winBoard[$k][$l]);
        }
    }
}
Log::write($sumUnmarked);
Log::write($sumUnmarked * $winningCall);
fclose($fh);
*/







//05-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent05Input.txt','r');
$board = array();
for($i=0;$i<1000;$i++){
    $lineVal = array();
    for($j=0;$j<1000;$j++){
        $lineVal[] = 0;
    }
    $board[] = $lineVal;
}
while ($line = fgets($fh)) {
    $coors = explode(" -> ", trim($line));
    $items = explode(",", $coors[0]);
    $x1 = intval($items[0]);
    $y1 = intval($items[1]);
    $items = explode(",", $coors[1]);
    $x2 = intval($items[0]);
    $y2 = intval($items[1]);
    if($x1 == $x2 || $y1 == $y2){
        for($i=min($x1,$x2);$i<=max($x1, $x2);$i++){
            for($j=min($y1,$y2);$j<=max($y1, $y2);$j++){
                $board[$i][$j] += 1;
            }
        }
    }
}
$count = 0;
for($i=0;$i<1000;$i++){
    for($j=0;$j<1000;$j++){
        if($board[$i][$j] > 1){
            $count += 1;
        }
    }
}
Log::write($count);
fclose($fh);
*/

//05-2
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent05Input.txt','r');
$board = array();
for($i=0;$i<1000;$i++){
    $lineVal = array();
    for($j=0;$j<1000;$j++){
        $lineVal[] = 0;
    }
    $board[] = $lineVal;
}
while ($line = fgets($fh)) {
    $coors = explode(" -> ", trim($line));
    $items = explode(",", $coors[0]);
    $x1 = intval($items[0]);
    $y1 = intval($items[1]);
    $items = explode(",", $coors[1]);
    $x2 = intval($items[0]);
    $y2 = intval($items[1]);
    if($x1 == $x2 || $y1 == $y2){
        for($i=min($x1,$x2);$i<=max($x1, $x2);$i++){
            for($j=min($y1,$y2);$j<=max($y1, $y2);$j++){
                $board[$i][$j] += 1;
            }
        }
    } else if (abs($x1 - $x2) == abs($y1 - $y2)){
        $posX = $x1;
        $posY = $y1;
        for($i=0;$i<=abs($x1 - $x2);$i++){
            $board[$posX][$posY] += 1;

            if($x1 < $x2){
                $posX += 1;
            } else {
                $posX -= 1;
            }
            if($y1 < $y2){
                $posY += 1;
            } else {
                $posY -= 1;
            }
        }
    }
}
$count = 0;
for($i=0;$i<1000;$i++){
    for($j=0;$j<1000;$j++){
        if($board[$i][$j] > 1){
            $count += 1;
        }
    }
}
Log::write($count);
fclose($fh);
*/





//06-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent06Input.txt','r');
$states = array();
while ($line = fgets($fh)) {
    $states = explode(",", trim($line));
}
for($j=0;$j<count($states);$j++){
    $states[$j] = intval($states[$j]);
}

$numberOfStatesEnd = 0;
for($i=1;$i<=80;$i++){
    //process day (reduce 1)
    for($j=0;$j<count($states);$j++){
        $states[$j] -= 1;
    }
    //Log::write($states);
    $numberOfStatesEnd = count($states);

    for($j=0;$j<$numberOfStatesEnd;$j++){
        if($states[$j] == 0){
            $states[$j] = 7;
            $states[] = 9;
        }
    }
}

Log::write($numberOfStatesEnd);
fclose($fh);
*/
//06-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent06Input.txt','r');
$states = array();
while ($line = fgets($fh)) {
    $states = explode(",", trim($line));
}
for($j=0;$j<count($states);$j++){
    $states[$j] = intval($states[$j]);
}

$numberOfStatesEnd = 0;
for($i=1;$i<=80;$i++){
    //process day (reduce 1)
    for($j=0;$j<count($states);$j++){
        $states[$j] -= 1;
    }
    //Log::write($states);
    $numberOfStatesEnd = count($states);

    for($j=0;$j<$numberOfStatesEnd;$j++){
        if($states[$j] == 0){
            $states[$j] = 7;
            $states[] = 9;
        }
    }
}

Log::write($numberOfStatesEnd);
fclose($fh);
*/

//06-2
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent06Input.txt','r');
$states = array();
while ($line = fgets($fh)) {
    $states = explode(",", trim($line));
}
$count = array();
for($j=0;$j<=9;$j++){
    $count[$j] = 0;
}
for($j=0;$j<count($states);$j++){
    $count[intval($states[$j])] += 1;
}

$numberOfStatesEnd = 0;
for($i=1;$i<=256;$i++){
    //process day (reduce 1)
    $temp = $count[0];
    $numberOfStatesEnd = 0;
    for($j=0;$j<=8;$j++){
        $count[$j] = $count[$j+1];
        $numberOfStatesEnd += $count[$j];
    }
    Log::write($i . " - " . $numberOfStatesEnd);
    //Log::write($count);

    $count[9] = $count[0];
    $count[7] += $count[0];
}

Log::write($numberOfStatesEnd);
fclose($fh);
*/






//07-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent07Input.txt','r');
$startPos = array();
while ($line = fgets($fh)) {
    $startPos = explode(",", trim($line));
}
$countPos = array();
$max = 0;
foreach($startPos as $sp){
    if(!isset($countPos[intval($sp)]) ){
        $countPos[intval($sp)] = 1;
    } else {
        $countPos[intval($sp)] += 1;
    }
    if($max < intval($sp)){
        $max = intval($sp);
    }
}
Log::write($max);
$minTotalMove = 9999999999;
for($i=0;$i<=$max;$i++){
    $chosenPos = $i;
    $totalMove = 0;
    //Log::write("chosen pos : " . $chosenPos);
    for($j=0;$j<=$max;$j++){
        if(!isset($countPos[$j])){

        } else {
            $dif = abs($chosenPos - $j);
            $totalMove += (($dif * $dif + $dif) / 2) * $countPos[$j];
        }
        //Log::write("increase " . $j . " - " . $totalMove);
    }
    if($minTotalMove > $totalMove){
        $minTotalMove = $totalMove;
        Log::write("final " . $i . " - " . $totalMove);
    }
}
//Log::write($countPos);
fclose($fh);
*/






//08-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent08Input.txt','r');
$countOne = 0;
$countFour = 0;
$countSeven = 0;
$countEight = 0;
while ($line = fgets($fh)) {
    $segments = explode(" | ", trim($line));
    $counts = explode(" ", trim($segments[1]));
    foreach($counts as $count){
        if(strlen(trim($count)) == 2){
            $countOne += 1;
        }
        else if(strlen(trim($count)) == 3){
            $countSeven += 1;
        }
        else if(strlen(trim($count)) == 4){
            $countFour += 1;
        }
        else if(strlen(trim($count)) == 7){
            $countEight += 1;
        }
    }
}
Log::write($countOne + $countFour + $countSeven + $countEight);
fclose($fh);*/


//08-2
/*
function findDigits($uniqs, $len){
    $res = "";
    foreach($uniqs as $uni){
        if(strlen($uni) == $len){
            $res = $uni;
        }
    }
    return $res;
}
function isContain($big, $small){
    //Log::write("big : " . $big . ", small : " . $small);
    $isWrong = false;
    $len = strlen($small);
    for($i=0;$i<$len;$i++){
        $test = strpos($big, substr($small, $i, 1));
        //Log::write("check char : " . substr($small, $i, 1) . " result : " . $test);
        if($test === false){
            //Log::write("wrong");
            $isWrong = true;
        }
    }
    return !$isWrong;
}
function findTheSame($results, $random){
    $lenRandom = strlen($random);
    for($i=0;$i<=9;$i++){
        $lenResult = strlen($results[$i]);
        if($lenResult == $lenRandom){
            $foundWrong = false;
            
            for($j=0;$j<$lenRandom;$j++){
                $test = strpos($results[$i], substr($random, $j, 1));
                if($test === false){
                    $foundWrong = true;
                }
            }
            if(!$foundWrong){
                return $i;
            }
        }
    }
    return -1;
}
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent08Input.txt','r');
$results = array();
$total = 0;
while ($line = fgets($fh)) {
    $segments = explode(" | ", trim($line));
    $digits = explode(" ", trim($segments[1]));
    $uniqs = explode(" ", trim($segments[0]));

    //find one
    $results[1] = findDigits($uniqs, 2);
    //find seven
    $results[7] = findDigits($uniqs, 3);
    //find four
    $results[4] = findDigits($uniqs, 4);
    //find eight
    $results[8] = findDigits($uniqs, 7);


    //find nine
    foreach($uniqs as $uniq){
        if(strlen($uniq) == 6){
            if(isContain($uniq, $results[4])){
                $results[9] = $uniq;
            }
        }
    }

    //find two
    foreach($uniqs as $uniq){
        if(strlen($uniq) == 5){
            if(!isContain($results[9], $uniq)){
                $results[2] = $uniq;
            }
        }
    }


    //find three
    foreach($uniqs as $uniq){
        if(strlen($uniq) == 5){
            if(isContain($uniq, $results[1])){
                $results[3] = $uniq;
            }
        }
    }

    //find five
    foreach($uniqs as $uniq){
        if(strlen($uniq) == 5){
            if(strcmp($uniq, $results[2]) != 0 && strcmp($uniq, $results[3]) != 0){
                $results[5] = $uniq;
            }
        }
    }

    //find zero
    foreach($uniqs as $uniq){
        if(strlen($uniq) == 6){
            if(isContain($uniq, $results[1])  && strcmp($uniq, $results[9]) != 0){
                $results[0] = $uniq;
            }
        }
    }

    //find six
    foreach($uniqs as $uniq){
        if(strlen($uniq) == 6){
            if(strcmp($uniq, $results[0]) != 0 && strcmp($uniq, $results[9]) != 0){
                $results[6] = $uniq;
            }
        }
    }
    Log::write(trim($line));
    Log::write($results);

    $strResultDigit = "";
    for($i=0;$i<count($digits);$i++){
        $strResultDigit .= findTheSame($results, $digits[$i]);
        //Log::write($digits[$i] . " - " . $strResultDigit);
    }
    Log::write(intval($strResultDigit));
    $total += intval($strResultDigit);

    //find top
    // $tempSevens = $sevens;
    // for($i=0;$i<2;$i++){
    //     $tempSevens = str_replace(substr($ones, $i, 1),"",$tempSevens);
    // }
    // $top = $tempSevens;

    // Log::write($ones . " - " . $sevens . " - " . $fours . " - " . $eights);
    // Log::write("Top : " . $top);
}
Log::write($total);
fclose($fh);
*/





//09-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent09Input.txt','r');
$map = array();
while ($line = fgets($fh)) {
    $hori = array();
    for($i=0;$i<strlen(trim($line));$i++){
        $hori[] = intval(substr($line, $i, 1));
    }
    $map[] = $hori;
} 

$totalLowest = 0;
for($i=0;$i<count($map);$i++){
    for($j=0;$j<count($map[$i]);$j++){
        $isLowest = true;
        if($i != 0) {
            if($map[$i-1][$j] <= $map[$i][$j]){
                $isLowest = false;
            }
        }
        if($i != count($map) - 1){
            if($map[$i+1][$j] <= $map[$i][$j]){
                $isLowest = false;
            }
        }
        if($j != 0){
            if($map[$i][$j-1] <= $map[$i][$j]){
                $isLowest = false;
            }
        }
        if($j != count($map[$i]) - 1){
            if($map[$i][$j+1] <= $map[$i][$j]){
                $isLowest = false;
            }
        }
        if($isLowest){
            //Log::write($i . " - " . $j . " - " . $map[$i][$j]);
            $totalLowest += 1 + $map[$i][$j];
        }
    }
}
Log::write($totalLowest);
fclose($fh);
*/


//09-2
/*
class MapCave{
    public $map;
    public $doneList;

    function MapCave($map){
        $this->map = $map;
        $this->doneList = array();
    }
    
    function getBasin($i, $j){
        if($i < 0 || $i >= count($this->map)) return 0;
        if($j < 0 || $j >= count($this->map[0])) return 0;
        if(isset($this->doneList[$i."-".$j])) return 0;
        if($this->map[$i][$j] >= 9) return 0;

        $this->doneList[$i."-".$j] = "0";

        $result = 1;
        if($i != 0){
            if($this->map[$i-1][$j] > $this->map[$i][$j]){
                $result += $this->getBasin($i-1, $j);
            }
        }
        if($i != count($this->map) - 1){
            if($this->map[$i+1][$j] > $this->map[$i][$j]){
                $result += $this->getBasin($i+1, $j);
            }
        }
        if($j != 0){
            if($this->map[$i][$j-1] > $this->map[$i][$j]){
                $result += $this->getBasin($i, $j-1);
            }
        }
        if($j != count($this->map[0]) - 1){
            if($this->map[$i][$j+1] > $this->map[$i][$j]){
                $result += $this->getBasin($i, $j+1);
            }
        }

        return $result;
    }
}
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent09Input.txt','r');
$map = array();
while ($line = fgets($fh)) {
    $hori = array();
    for($i=0;$i<strlen(trim($line));$i++){
        $hori[] = intval(substr($line, $i, 1));
    }
    $map[] = $hori;
} 

$totalLowest = 0;
$result = array();
for($i=0;$i<count($map);$i++){
    for($j=0;$j<count($map[$i]);$j++){
        $isLowest = true;
        if($i != 0) {
            if($map[$i-1][$j] <= $map[$i][$j]){
                $isLowest = false;
            }
        }
        if($i != count($map) - 1){
            if($map[$i+1][$j] <= $map[$i][$j]){
                $isLowest = false;
            }
        }
        if($j != 0){
            if($map[$i][$j-1] <= $map[$i][$j]){
                $isLowest = false;
            }
        }
        if($j != count($map[$i]) - 1){
            if($map[$i][$j+1] <= $map[$i][$j]){
                $isLowest = false;
            }
        }
        if($isLowest){
            Log::write($i . " - " . $j . " - " . $map[$i][$j]);
            $mapCave = new MapCave($map);
            $result[] = $mapCave->getBasin($i, $j);
            //$totalLowest += 1 + $map[$i][$j];
        }
    }
}
rsort($result);
Log::write($result);
Log::write($result[0] * $result[1] * $result[2]);
fclose($fh);
*/





//10-1
/*
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent10Input.txt','r');
$wrongPoints = 0;
$incompleteLinePoints = array();
while ($line = fgets($fh)) {
    $string = trim($line);
    $idxError = -1;
    $stack = "";
    $wrongChar = "";
    for($i=0;$i<strlen($string) && $idxError == -1;$i++){
        if(strcmp(substr($string,$i,1), "(") == 0 || 
            strcmp(substr($string,$i,1), "[") == 0 || 
            strcmp(substr($string,$i,1), "{") == 0 || 
            strcmp(substr($string,$i,1), "<") == 0) {
            $stack .= substr($string,$i,1);
        } else {
            if(strcmp(substr($string,$i,1), ")") == 0 && 
                strcmp(substr($stack,strlen($stack)-1,1), "(") == 0){
                $stack = substr($stack, 0, strlen($stack) - 1);
            } else if (strcmp(substr($string,$i,1), "]") == 0 && 
                strcmp(substr($stack,strlen($stack)-1,1), "[") == 0){
                $stack = substr($stack, 0, strlen($stack) - 1);
            } else if (strcmp(substr($string,$i,1), "}") == 0 && 
                strcmp(substr($stack,strlen($stack)-1,1), "{") == 0){
                $stack = substr($stack, 0, strlen($stack) - 1);
            } else if (strcmp(substr($string,$i,1), ">") == 0 && 
                strcmp(substr($stack,strlen($stack)-1,1), "<") == 0){
                $stack = substr($stack, 0, strlen($stack) - 1);
            } else {
                $idxError = $i;
                $wrongChar = substr($string,$i,1);
            }
        }
    }
    //Log::write($idxError . " - " . $wrongChar);

    if(strcmp($wrongChar, ")") == 0){
        $wrongPoints += 3;
    } else if(strcmp($wrongChar, "]") == 0){
        $wrongPoints += 57;
    } else if(strcmp($wrongChar, "}") == 0){
        $wrongPoints += 1197;
    } else if(strcmp($wrongChar, ">") == 0){
        $wrongPoints += 25137;
    } else { // for 10-2
        $incompleteLinePoint = 0;
        for($i=strlen($stack) - 1;$i>=0;$i--){
            $incompleteLinePoint *= 5;
            if(strcmp(substr($stack,$i,1), "(") == 0){
                $incompleteLinePoint += 1;
            } else if(strcmp(substr($stack,$i,1), "[") == 0) {
                $incompleteLinePoint += 2;
            } else if(strcmp(substr($stack,$i,1), "{") == 0) {
                $incompleteLinePoint += 3;
            } else if(strcmp(substr($stack,$i,1), "<") == 0) {
                $incompleteLinePoint += 4;
            }
        }
        Log::write($stack . " - " . $incompleteLinePoint);
        $incompleteLinePoints[] = $incompleteLinePoint;
    }
}
Log::write($wrongPoints);
rsort($incompleteLinePoints);
Log::write($incompleteLinePoints);
fclose($fh);
*/





//11-1
/*
function printMap($map){
    for($j=0;$j<10;$j++){
        $line = "";
        for($k=0;$k<10;$k++){
            $line .= $map[$j][$k] . " ";
        }
        Log::write($line);
    }
}

function addSingleBright($map, $i, $j){
    if($i < 0 || $j < 0 || $i >= 10 || $j >= 10) return $map;
    if($map[$i][$j] == 10){
        $map[$i][$j] += 1;
        $map = processFlash($map, $i, $j);
        return $map;
    }
    $map[$i][$j] += 1;
    if($map[$i][$j] == 10){
        $map = processFlash($map, $i, $j);
    }
    return $map;
}

function processFlash($map, $i, $j){
    if($i < 0 || $j < 0 || $i >= 10 || $j >= 10) return $map;

    $map[$i][$j] += 1;
    //Log::write("Process flash " . $i . " - " . $j);
    // Log::write("before " . $i . " - " . $j);
    // printMap($map);

    $map = addSingleBright($map, $i-1, $j-1);
    $map = addSingleBright($map, $i-1, $j);
    $map = addSingleBright($map, $i-1, $j+1);
    $map = addSingleBright($map, $i, $j-1);
    $map = addSingleBright($map, $i, $j+1);
    $map = addSingleBright($map, $i+1, $j-1);
    $map = addSingleBright($map, $i+1, $j);
    $map = addSingleBright($map, $i+1, $j+1);

    // Log::write("after " . $i . " - " . $j);
    // printMap($map);

    return $map;
}


$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent11Input.txt','r');
$map = array();
while ($line = fgets($fh)) {
    $tempLine = array();
    for($i=0;$i<strlen(trim($line));$i++){
        $tempLine[] = intval(substr($line, $i, 1));
    }
    $map[] = $tempLine;
}
//Log::write($map);

$itNo = 100;
$countFlash = 0;
$isSync = false;
for($i=0;$i<$itNo || !$isSync;$i++){
    //add all by one
    for($j=0;$j<10;$j++){
        for($k=0;$k<10;$k++){
            $map[$j][$k] += 1;
        }
    }

    // Log::write("after add one ");
    // printMap($map);

    for($j=0;$j<10;$j++){
        for($k=0;$k<10;$k++){
            if($map[$j][$k] == 10){
                // Log::write("here " . $j . " - " . $k);
                
                // Log::write("before " . $j . " - " . $k);
                // printMap($map);

                $map = processFlash($map, $j, $k);

                // Log::write("after " . $j . " - " . $k);
                // printMap($map);
            }
        }
    }

    
    for($j=0;$j<10;$j++){
        for($k=0;$k<10;$k++){
            if($map[$j][$k] >= 10){
                $map[$j][$k] = 0;
                $countFlash += 1;
            }
        }
    }



    //check sync
    //for 11-2
    $foundNotZero = false;
    for($j=0;$j<10;$j++){
        for($k=0;$k<10;$k++){
            if($map[$j][$k] != 0){
                $foundNotZero = true;
            }
        }
    }

    if(!$foundNotZero){
        $isSync = true;
    }

    
    Log::write("Iteration number : " . ($i+1));
    Log::write("Flash : " . $countFlash);
    printMap($map);
}
fclose($fh);
*/





//12-1
/*
function numOfPath($caves, $connect, $completedCaves){
    // Log::write($completedCaves);
    $lastCave = $completedCaves[count($completedCaves) - 1];
    if(strcmp($lastCave,"end") == 0) return 1;

    $result = 0;
    foreach($caves as $cave){
        if($connect[$lastCave][$cave] == 1 && strcmp($cave,"start") != 0){ // check if connected
            $nextCave = $cave;
            if(ord(substr($nextCave, 0, 1)) >= 97){
                $listOfCompletedSmallCaves = array();
                $foundAllowedDuplicateSmallCave = false;
                for($j=0;$j<count($completedCaves) && !$foundAllowedDuplicateSmallCave;$j++){
                    if(ord(substr($completedCaves[$j], 0, 1)) >= 97){
                        if(isset($listOfCompletedSmallCaves[$completedCaves[$j]])){
                            $foundAllowedDuplicateSmallCave = true;
                        } else {
                            $listOfCompletedSmallCaves[$completedCaves[$j]] = $completedCaves[$j];
                        }
                    }
                }
                //Log::write($nextCave);

                if(!$foundAllowedDuplicateSmallCave){
                    //Log::write("allowed");
                    $tempCompleted = $completedCaves;
                    $tempCompleted[] = $nextCave;
                    $result += numOfPath($caves, $connect, $tempCompleted);
                } else {
                    //Log::write("duplicate");
                    //check if duplicated
                    $foundDuplicate = false;
                    for($j=0;$j<count($completedCaves);$j++){
                        if(strcmp($completedCaves[$j], $nextCave) == 0){
                            $foundDuplicate = true;
                        }
                    }

                    if(!$foundDuplicate){
                        //Log::write("but allowed");
                        $tempCompleted = $completedCaves;
                        $tempCompleted[] = $nextCave;
                        $result += numOfPath($caves, $connect, $tempCompleted);
                    }
                }



            } else {
                $tempCompleted = $completedCaves;
                $tempCompleted[] = $nextCave;
                $result += numOfPath($caves, $connect, $tempCompleted);
            }
        }
    }
    return $result;
}


$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent12Input.txt','r');
$caves = array();
while ($line = fgets($fh)) {
    $items = explode("-",trim($line));
    if(!isset($caves[$items[0]])){
        $caves[$items[0]] = $items[0];
    }
    if(!isset($caves[$items[1]])){
        $caves[$items[1]] = $items[1];
    }
}

$connect = array();
foreach($caves as $caveA){
    $connect[$caveA] = array();
    foreach($caves as $caveB){
        $connect[$caveA][$caveB] = 0;
    }
}
fclose($fh);

$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent12Input.txt','r');
while ($line = fgets($fh)) {
    $items = explode("-",trim($line));
    $connect[$items[0]][$items[1]] = 1;
    $connect[$items[1]][$items[0]] = 1;
}
fclose($fh);


// Log::write($caves);
// Log::write($connect);

$completedCaves = array();
$completedCaves[] = 'start';

$result = numOfPath($caves, $connect, $completedCaves);
Log::write($result);
*/







//13-1
function printPaper($paper, $maxX, $maxY){
    for($j=0;$j<=$maxY;$j++){
        $str = "";
        for($i=0;$i<=$maxX;$i++){
            if($paper[$i][$j] == 0) $str .= ".";
            else $str .= "#";
            // $str .= $paper[$i][$j];
        }
        Log::write($str);
    }
}
$fh = fopen(PATH_CONTROLLERS . 'signin/advent/2021advent13Input.txt','r');
$listOfCoordinates = array();
$listOfFoldingPositions = array();
while ($line = fgets($fh)) {
    if(strcmp(substr(trim($line),0,4), "fold") == 0){
        $items = explode(" ",trim($line));
        $listOfFoldingPositions[] = explode("=", $items[2]);
    } else {
        if(strlen(trim($line)) > 1){
            $listOfCoordinates[] = explode(",",trim($line));
        }
    }
}
for($i=0;$i<count($listOfCoordinates);$i++){
    $listOfCoordinates[$i][0] = intval($listOfCoordinates[$i][0]);
    $listOfCoordinates[$i][1] = intval($listOfCoordinates[$i][1]);
}
for($i=0;$i<count($listOfFoldingPositions);$i++){
    $listOfFoldingPositions[$i][1] = intval($listOfFoldingPositions[$i][1]);
}

// Log::write($listOfCoordinates);
// Log::write($listOfFoldingPositions);

$maxX = 0;
$maxY = 0;
for($i=0;$i<count($listOfCoordinates);$i++){
    if($maxX < $listOfCoordinates[$i][0]){
        $maxX = $listOfCoordinates[$i][0];
    }
    if($maxY < $listOfCoordinates[$i][1]){
        $maxY = $listOfCoordinates[$i][1];
    }
}

$paper = array();
for($i=0;$i<=$maxX;$i++){
    $paper[$i] = array();
    for($j=0;$j<=$maxY;$j++){
        $paper[$i][$j] = 0;
    }
}


for($i=0;$i<count($listOfCoordinates);$i++){
    $x = $listOfCoordinates[$i][0];
    $y = $listOfCoordinates[$i][1];
    $paper[$x][$y] = 1;
}

for($idx=0;$idx <count($listOfFoldingPositions);$idx++){
// for($idx=0;$idx <1;$idx++){
    $axis = $listOfFoldingPositions[$idx][0];
    $pos = $listOfFoldingPositions[$idx][1];

    if($axis == "x"){
        $newMaxX = max($pos - 1, $maxX - $pos - 1 );
        $newMaxY = $maxY;

        $newPaper = array();

        for($i=0;$i<=$newMaxX;$i++){
            $leftX = $pos - ($newMaxX + 1) + $i;
            $rightX = $pos + ($newMaxX + 1) - $i;
            // Log::write($pos . " - " . $newMaxX . " - " . $leftX . " - " . $rightX);

            $newPaper[$i] = array();
            for($j=0;$j<=$newMaxY;$j++){
                $valLeft = 0;
                if($leftX >= 0 && $leftX <= $maxX) $valLeft = $paper[$leftX][$j];
                $valRight = 0;
                if($rightX >= 0 && $rightX <= $maxX) $valRight = $paper[$rightX][$j];

                $newPaper[$i][$j] = $valLeft == 1 || $valRight == 1 ? 1 : 0;
            }
        }

        $maxX = $newMaxX;
        $maxY = $newMaxY;
        $paper = $newPaper;
    } else {
        $newMaxX = $maxX;
        $newMaxY = max($pos - 1, $maxY - $pos - 1);

        $newPaper = array();

        for($i=0;$i<=$newMaxX;$i++){
            $newPaper[$i] = array();
            for($j=0;$j<=$newMaxY;$j++){
                $topY = $pos - ($newMaxY + 1) + $j;
                $bottomY = $pos + ($newMaxY + 1) - $j;

                // Log::write($i . " - " . $topY . " - " . $bottomY);
                $valTop = 0;
                if($topY >= 0 && $topY <= $maxY) $valTop = $paper[$i][$topY];
                $valBottom = 0;
                if($bottomY >= 0 && $bottomY <= $maxY) $valBottom = $paper[$i][$bottomY];

                $newPaper[$i][$j] = ($valTop == 1 || $valBottom == 1) ? 1 : 0;
            }
        }

        $maxX = $newMaxX;
        $maxY = $newMaxY;
        $paper = $newPaper;
    }

    // Log::write("new max : " . $newMaxX . " - " . $newMaxY);
    // printPaper($paper, $maxX, $maxY);
    $total = 0;
    for($i=0;$i<=$maxX;$i++){
        for($j=0;$j<=$maxY;$j++){
            $total += $paper[$i][$j];
        }
    }
    Log::write($total);
}
printPaper($paper, $maxX, $maxY);

fclose($fh);
?>
