+ Задача № 37. Проверить, является ли натуральное число счастливым билетом

Особенность задачи в том , что нам неизвестно заранее с каким разрядом число рассматривается .

 <?php
 
//Пишем любое число
$a=8824567; 
// Число цифр в числе 
$count=1 ;
   // Пробуем подсчитать количество разрядов врядли 
      for ($i=1 ;  $a / pow (10,$i) >=1 ; $i++)
      {
        $count++ ;
      }  
      echo "Само число: ",$a , "<BR>";
    echo "Число знаков : " ,$count,"<BR>"  ;  
  //Определили количество цифр (разрядов) в числе 
  /*Теперь запишем условие : 1) если число имеет нечётное количество 
знаков , то вычитаем из количества знаков единичу и делим пополам и 
записываем результат в переменную $j , и вычисляем сумму всех цифр 
от первого цифры до переменной $j .Далее вычисляем сумму всех цифр
от переменной $j до числа $count (числа цифр) . Как посчитать сумму цифр ?  */
 //_________________________________________________________________________________________________________________ 
 /* !!! Очень важно заметить ! что % - это !целочисленный! остаток 
от деления числа на другое число. Даже если мы имеем число , 345,34 , 
и 345,34 % 10 мы имеем не 5,34 , а именно только 5  */
// $r и $l -это переменные суммы соответственно правой и левой
// частей числа 
   
  $r=0;
  $l=0;
   // Если количество цифр чётно то выполняем одну 
// группу циклов , со своими счётчиками
// если нечётно , то с другими
   if ($count % 2 == 0 )
      {
// Здесь количество цифр чётно
// значит справа проходим от последней
// цифры с порядком $count и до средней цифры
// $count/2  + 1 
              for ($j=$count ; $j >=  $count/2+1 ;$j--)
              {
// Считаем сумму правых цифр 
// Берем остаток от деления на 10 
                 $r  = $r  + $a % 10 ;
// Делим само число на 10 , чтобы передвигаться 
// налево 
                 $a= $a/10 ;
                                          
              }
// Считаем цифры справа и налево для левой часи
// Здесь счёт от count/2 до 1
               for ($j=$count/2; $j >=  1 ;$j--)
              {
// Так же считаем сумму цифр
                 $l  = $l  + $a % 10 ;
                 $a= $a/10 ;
                                          
              }
//Условие "счастливости"
               if ($r == $l)
               {
                   echo "Число счастливое " ;
               }
               else
               {
                   echo "Число не счастливое" ;
               }      
      }
// Если число нечётно то код вобщем такой же
// но , границы изменения счётчика другие 
      else
      {
              for ($j=$count ; $j >= ($count-1)/2+2 ;$j--) 
              {
                 $r  = $r  + $a % 10 ;
                 $a= $a/10 ;
                // echo "Нечетное число знаков и \$r=",$r;
                                          
              }
                $a=$a/10;
                for ($j=($count-1)/2; $j >=1   ;$j--)   
              {
                   
                 $l  = $l  + $a % 10 ;
                 $a= $a/10 ;
                // echo "Нечетное число знаков и \$l=",$l;
                                          
              }
               if ($r == $l)
               {
                   echo "Число счастливое " ;
               }
               else
               {
                   echo "Число не счастливое" ;
               }
      }
 ?>
 
vedro-compota's picture

получилось ли подсчитать число разрядов вашим способом?

  • если предположить, что переданная строка является числом, что проще преобразовать её в массив и вызвать
    count($yourarray)
  • или ещё быстрее вызвать
    strlen($yourstr)

_____________
матфак вгу и остальная классика =)

fgh's picture

Да получилось .

$a=8824567; 
// Число цифр в числе 
$count=1 ;
   // Пробуем подсчитать количество разрядов врядли 
      for ($i=1 ;  $a / pow (10,$i) >=1 ; $i++)
      {
        $count++ ;
      }  

А далее осуществил подсчёт суммы разрядов "слева" переменная $l и справа "r" . Для меня стало настоящим открытием :) когда я узнал , что если данное число "$a" равно 99,9 , то

$a % 10 

- данное действие вернёт именно 9 , а не "9,9"
Сумма подсчитывается в зависимости от числа разрядов. Оно может быть чётным или нечётным. Чем недоволен - код громоздкий . Надо бы решить задачу болеее оптимально .

vedro-compota's picture

. Чем недоволен - код громоздкий . Надо бы решить задачу болеее оптимально .

да, здесь просто надо проходить строку "до середины" слева и справа. и число шагов до середин определить до переборов - тогда их не придётся писать дважды для случая чётности/нечётности.
Блоку перебора должно быть "всё равно" насчёт того чётно или нет число символов строки, которое им перебирается - он просто делает N шагов слева и N справа.
Попробуйте реализовать этот повход, когда вернётесь к данной задаче.

_____________
матфак вгу и остальная классика =)

fgh's picture

Да , функция count для массива или строки - это более компактно , но хочется понять , как работают сами функции . Это очень интересно. Хотя время выполнения кода в случае вызова готовой функции, наверное, на порядки выше чем работа своего кода, а для большого кода всей программы это становится существенно.

vedro-compota's picture

Да , функция count для массива или строки

для строки я предлагал другую функцию

но хочется понять , как работают сами функции

точнее, вы хотите реализовать её сами - при первом решении задачи это похвально. Затем рекомендую ниже добавить более оптимальное решение с учётом всех комментариев.

время выполнения кода в случае вызова готовой функции, наверное, на порядки выше чем работа своего кода,

точнее, готовые функции работают намного быстрее, что, как я думаю, вы и подразумевали.

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

ваш код не прокомментирован.
добавьте краткие комментарии к циклам и блокам условий

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

// Если число нечётно то код вобщем такой же
// но , границы изменения счётчика другие

вот вы сами указали основную проблему решения - вам нужно просто заранее рассчитать условия для счётчика, и всё - а не дублировать код циклов. Потом перепишите решение ниже предыдущего, чтобы была видна разница.

_____________
матфак вгу и остальная классика =)

Сокращённый вариант.

#!/usr/bin/php
<?php
//Пишем любое число
$a = 31882456713; 

// подсчитать количество разрядов
for ( $count = 1 ; $a / pow(10,$count) >= 1 ; $count++);
	 
echo "Само число: ",$a , "\n";
echo "Число знаков : " ,$count,"\n"  ;

$r=0;	//сумма

// отсекаем от $a правую половину и середину
$b =  $a / pow(10, (integer) ($count / 2) + $count % 2 );

for ($j=$count ; $j >= (integer) ($count / 2) + $count % 2 + 1 ; $j--)
{
	$r  = $r  + $a % 10 - $b % 10;
	$a = $a / 10;	// Делим числа на 10 , чтобы передвигаться налево
	$b = $b / 10;                                           
}

if ( ( $r == 0 ) and ( $count > 1 ) )
	echo "Число счастливое\n" ;
else
	echo "Число не счастливое\n" ;
?>