BG Development


  Reply to this topicStart new topicStart Poll

> Advent of code day 3
DvDty
  Публикувано на: 03-12-2017, 17:00
Quote Post



Име:
Група: Потребител
Ранг: Новопостъпил

Мнения: 37
Регистриран на: 22.10.14



Линк за задачата
или снимка на условието:
user posted image

Имах затруднения с решаването на задачата (php) и потърсих решение.
Открих това в reddit:
CODE
function run_the_code($input) {
   // find the layer it's on
   $layerWidth = 1;
   $layerMax = 1;
   while ($input > $layerMax) {
       $layerWidth += 2;
       $layerMax = $layerWidth ** 2;
   }

   $midway = $layerMax - (($layerWidth - 1) * 2);

   if ($input == $midway || $input == $layerMax) {
       return $layerWidth - 1;
   }
   if ($input > $midway) {
       $diff = $layerMax - $input;
   }
   if ($input < $midway) {
       $diff = $midway - $input;
   }
   if ($diff >= $layerWidth) {
       $diff -= (($layerWidth - 1) / 2);
   }
   else {
       $diff = $layerWidth - 1 - $diff;
   }

   return $diff;
}


Кодът ми реши задачата (и тази на човека пост-нал кода), но мисля, че има грешка в него.
CODE
if ($diff >= $layerWidth) {
            $diff -= (($layerWidth - 1) / 2);
      }

В тази част, ако вземем за пример input = 10, получаваме width = 5, max = 25 и midway = 17.
Влизаме в 3-тия if, от който идва diff = midway - input = 7.
След това в следващият if, и получаваме: diff - ((width - 1) / 2) = 7 - ((5 - 1) / 2) = 5, а отговорът трябва да е 3.
Аз ли бъркам някъде или решението наистина е грешно?
PMEmail Poster
Top
martinradev
Публикувано на: 03-12-2017, 20:18
Quote Post



Име:
Група: Потребител
Ранг: Активен

Мнения: 244
Регистриран на: 06.08.14



Какво точно питаш?
PMEmail Poster
Top
RoYaL
Публикувано на: 03-12-2017, 23:00
Quote Post



Име:
Група: Потребител
Ранг: Старо куче

Мнения: 853
Регистриран на: 21.08.05



QUOTE (DvDty @ 03-12-2017, 17:00)
Линк за задачата
или снимка на условието:
user posted image

Имах затруднения с решаването на задачата (php) и потърсих решение.
Открих това в reddit:
CODE
function run_the_code($input) {
   // find the layer it's on
   $layerWidth = 1;
   $layerMax = 1;
   while ($input > $layerMax) {
       $layerWidth += 2;
       $layerMax = $layerWidth ** 2;
   }

   $midway = $layerMax - (($layerWidth - 1) * 2);

   if ($input == $midway || $input == $layerMax) {
       return $layerWidth - 1;
   }
   if ($input > $midway) {
       $diff = $layerMax - $input;
   }
   if ($input < $midway) {
       $diff = $midway - $input;
   }
   if ($diff >= $layerWidth) {
       $diff -= (($layerWidth - 1) / 2);
   }
   else {
       $diff = $layerWidth - 1 - $diff;
   }

   return $diff;
}


Кодът ми реши задачата (и тази на човека пост-нал кода), но мисля, че има грешка в него.
CODE
if ($diff >= $layerWidth) {
            $diff -= (($layerWidth - 1) / 2);
      }

В тази част, ако вземем за пример input = 10, получаваме width = 5, max = 25 и midway = 17.
Влизаме в 3-тия if, от който идва diff = midway - input = 7.
След това в следващият if, и получаваме: diff - ((width - 1) / 2) = 7 - ((5 - 1) / 2) = 5, а отговорът трябва да е 3.
Аз ли бъркам някъде или решението наистина е грешно?

width-a е изманипулиран в while-a обаче?
PMEmail Poster
Top
DvDty
Публикувано на: 05-12-2017, 19:42
Quote Post



Име:
Група: Потребител
Ранг: Новопостъпил

Мнения: 37
Регистриран на: 22.10.14



QUOTE (RoYaL @ 03-12-2017, 23:00)
QUOTE (DvDty @ 03-12-2017, 17:00)
Линк за задачата
или снимка на условието:
[ IMG ] https://imgur.com/9eAhm45.png[/IMG]

Имах затруднения с решаването на задачата (php) и потърсих решение.
Открих това в reddit:
CODE
function run_the_code($input) {
   // find the layer it's on
   $layerWidth = 1;
   $layerMax = 1;
   while ($input > $layerMax) {
       $layerWidth += 2;
       $layerMax = $layerWidth ** 2;
   }

   $midway = $layerMax - (($layerWidth - 1) * 2);

   if ($input == $midway || $input == $layerMax) {
       return $layerWidth - 1;
   }
   if ($input > $midway) {
       $diff = $layerMax - $input;
   }
   if ($input < $midway) {
       $diff = $midway - $input;
   }
   if ($diff >= $layerWidth) {
       $diff -= (($layerWidth - 1) / 2);
   }
   else {
       $diff = $layerWidth - 1 - $diff;
   }

   return $diff;
}


Кодът ми реши задачата (и тази на човека пост-нал кода), но мисля, че има грешка в него.
CODE
if ($diff >= $layerWidth) {
            $diff -= (($layerWidth - 1) / 2);
      }

В тази част, ако вземем за пример input = 10, получаваме width = 5, max = 25 и midway = 17.
Влизаме в 3-тия if, от който идва diff = midway - input = 7.
След това в следващият if, и получаваме:  diff - ((width - 1) / 2) = 7 - ((5 - 1) / 2) = 5, а отговорът трябва да е 3.
Аз ли бъркам някъде или решението наистина е грешно?

width-a е изманипулиран в while-a обаче?

Което аз взимам в предвид - при input 10, минавам 2 пъти през цикъла, и width става 1->3->5.

Едит: Решението от reddit е грешно. Грешният иф (последният), трябва да се замени с този:
CODE
if ($diff >= $layerWidth) {
   $diff = $layerWidthHalf + abs($diff - ($layerWidth - 1) - $layerWidthHalf);
} else {
   $diff = abs($diff - $layerWidthHalf) + $layerWidthHalf;
}
PMEmail Poster
Top
hristonev
Публикувано на: 11-12-2017, 12:20
Quote Post



Име:
Група: Потребител
Ранг: Посетител

Мнения: 70
Регистриран на: 19.09.17



Интересна задачка icon_wink.gif .
CODE

$param = (count($argv) > 1) ? (int)$argv[1] : null;
if(is_null($param) || $param < 0){
   throw new Exception("Param 1 (positive integer) missing!");
}

$maxSteps = ceil(sqrt($param)) - 1;
$cornerNumber = pow($maxSteps + 1, 2);

$cornerCollection = [
   abs($cornerNumber - $param) => $cornerNumber,
   abs($cornerNumber - $maxSteps - $param) => ($cornerNumber - $maxSteps),
   abs($cornerNumber - $maxSteps * 2 - $param) => ($cornerNumber - $maxSteps * 2),
];
ksort($cornerCollection);

// Upper/right part of matrix
if($maxSteps % 2 !== 0 && ($cornerNumber - $maxSteps) == current($cornerCollection)){
   $maxSteps++;
}

$result = $maxSteps - abs(array_shift($cornerCollection) - $param);

echo "Reach 1 in ". $result. " steps.\n";

Това е моето решение.
PMEmail Poster
Top
purjola
Публикувано на: 12-12-2017, 01:42
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 1609
Регистриран на: 18.10.11



@hristonev

$param може да е с if ($argc < 2) die("GTFO");
$maxSteps при закръгляване нагоре/надолу има натрупваща се грешка
$cornerNumber може да е ($maxSteps++ ** 2), нямам идея дали работи
използването на abs води до излишни сравнения
PMEmail Poster
Top
hristonev
Публикувано на: 12-12-2017, 08:20
Quote Post



Име:
Група: Потребител
Ранг: Посетител

Мнения: 70
Регистриран на: 19.09.17



@purjola

1. argc проверява за брой аргументи. Мен ми е нужен един аргумент по-голям от 0 по задание.
2. ceil се извиква 1 път за живота на скрипта, върху какво натрупва грешка?!
3. ($maxSteps++ ** 2) няма да работи icon_smile.gif предвид положението на ++ (++$maxSteps ** 2) ще работи. И защо трябва да е със съкратен синтаксис?
4. abs не се ползва за сравнение а за кастване към положително число.

Въобще не виждам нищо градивно в този коментар.
PMEmail Poster
Top
purjola
Публикувано на: 13-12-2017, 01:13
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 1609
Регистриран на: 18.10.11



1. Проверяваш излишно в $argv колко аргумента са подадени. $argc предлага това по дифолт
2. Колкото повече стъпки в $param, толкова повече натрупване
3. Не знам, мен лично повече ми харесва, спестяваш два спейса. Иначе не съм стриктен, ++съмшит е ок
4. Преобразуваш резултата винаги да е положителен, това ще е всеки път когато викаш функцията
PMEmail Poster
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2015 | BG Development | All Rights Reserved
RSS 2.0