За последние 24 часа нас посетил 17921 программист и 1567 роботов. Сейчас ищут 850 программистов ...

Алгоритмы & Полезности

Тема в разделе "Решения, алгоритмы", создана пользователем Chushkin, 4 авг 2015.

  1. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    16) Дополнение чисел нулями в соответствии с порядком
    или "разбиение числа на 10-ки, 100-и и т.д."

    Пример с array_walk() для простой строки, типа "{не_цифры}*{цифры}*":
    PHP:
    1. $str = 'Г389';
    2.  
    3. $array = preg_split('/(?=\d)/u', $str, null, PREG_SPLIT_NO_EMPTY);
    4. array_walk($array, function(&$v, $k, $i) {
    5.         if(is_numeric($v)) $v = str_pad($v, $i - $k, '0'); $i--;
    6.     }, count($array));
    7.  
    8. var_dump($array);
    9. /*
    10. Результат:
    11. array(4) {
    12.   [0]=> string(2) "Г"
    13.   [1]=> string(3) "300"
    14.   [2]=> string(2) "80"
    15.   [3]=> string(1) "9"
    16. }
    17. */
     
    denis01 нравится это.
  2. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    17) Удалить идущие подряд элементы с одинаковыми значениями

    Сложный, но интересный вариант с функциями обработки массивов:
    PHP:
    1. $arr = array(
    2.     '14:50' => 'Быстрые и громкие',
    3.     '15:40' => 'Махинаторы',
    4.     '16:05' => 'Махинаторы',
    5.     '16:35' => 'Золотая лихорадка',
    6.     '17:30' => 'Выжить любой ценой',
    7.     '18:25' => 'Выжить любой ценой',
    8.     '19:20' => 'Выжить любой ценой',
    9.     '20:15' => 'Как это устроено?',
    10.     '20:40' => 'Охотники за складами: Британия',
    11.     '21:10' => 'Склады: битва в Канаде',
    12.     '21:40' => 'Багажные войны',
    13.     '22:05' => 'Махинаторы',
    14.     '22:30' => 'Махинаторы',
    15.     '23:00' => 'Как это устроено?',
    16.     );
    17.  
    18. $new =  array_filter(
    19.           array_combine(
    20.             array_keys($arr) + [-1=> false], // дополнить до размера второго параметра
    21.             array_map(
    22.               function($v1, $v2) { return ($v1 == $v2) ? false : $v1; },
    23.               $arr,
    24.               [-1=> false] + $arr // сдвинуть на 1
    25.             )
    26.           )
    27.         );
    28.  
    29. echo 'Исходный массив: (size=' . count($arr) . ') ';
    30. print_r($arr);
    31. echo 'Полученный массив: (size=' . count($new) . ') ' ;
    32. print_r($new);
    Результат:
    Код (Text):
    1. Исходный массив: (size=14) Array
    2. (
    3.     [14:50] => Быстрые и громкие
    4.     [15:40] => Махинаторы
    5.     [16:05] => Махинаторы
    6.     [16:35] => Золотая лихорадка
    7.     [17:30] => Выжить любой ценой
    8.     [18:25] => Выжить любой ценой
    9.     [19:20] => Выжить любой ценой
    10.     [20:15] => Как это устроено?
    11.     [20:40] => Охотники за складами: Британия
    12.     [21:10] => Склады: битва в Канаде
    13.     [21:40] => Багажные войны
    14.     [22:05] => Махинаторы
    15.     [22:30] => Махинаторы
    16.     [23:00] => Как это устроено?
    17. )
    18. Полученный массив: (size=10) Array
    19. (
    20.     [14:50] => Быстрые и громкие
    21.     [15:40] => Махинаторы
    22.     [16:35] => Золотая лихорадка
    23.     [17:30] => Выжить любой ценой
    24.     [20:15] => Как это устроено?
    25.     [20:40] => Охотники за складами: Британия
    26.     [21:10] => Склады: битва в Канаде
    27.     [21:40] => Багажные войны
    28.     [22:05] => Махинаторы
    29.     [23:00] => Как это устроено?
    30. )
    * Задача и исходные данные из той темы .
     
    #27 Chushkin, 26 июн 2017
    Последнее редактирование: 26 июн 2017
    forever_young и igordata нравится это.
  3. gruth

    gruth Активный пользователь

    С нами с:
    13 май 2017
    Сообщения:
    224
    Симпатии:
    18
    18) Получить из первого массива определенные значения

    PHP:
    1. $array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
    2. $search = ['a' => null, 'd' => null, 'e' => null, 'f' => 9];
    3. print_r(array_replace($search, array_intersect_key($array, $search)));
     
    denis01 нравится это.
  4. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    19) 1. Составить массив, ключами в котором будут названия континентов (на английском - Africa), значениями — массивы из латинских названий зверей (например, Mammuthus columbi – можно найти в карточке статистики о животном справа). Найдите различных зверей и составьте массив так, чтобы для ключа Africa у вас значением был бы массив из зверей, там обитавших или обитающих. Выберите только один континент для каждого животного. Пусть у вас получится 10-15 зверей.

    2.Теперь найдите всех зверей, название которых состоит из двух слов. Составьте из них новый массив.

    3.Случайно перемешайте между собой первые и вторые слова названий животных так, чтобы на выходе мы получили выдуманных, фантазийных животных. Название фантазийного животного должно начинаться с первого слова реального названия животного. Важно, чтобы каждый кусочек был использован и не повторялся более одного раза. Ничего страшного, если в результате перемешивания иногда будут получаться реальные животные. Вывести этих животных на экран.

    PHP:
    1. <?php
    2. $continents = [
    3.     'Africa' => [
    4.         'African elephant',
    5.         'Hippo',
    6.         'Giraffe',
    7.         'Crocodile',
    8.         'Spotted hyena',
    9.         'Zebra',
    10.         'Chimpanzee',
    11.         'Python',
    12.         'Scorpio',
    13.         'Canna',
    14.     ],
    15.     'Eurasia' => [
    16.         'Tapir',
    17.         'Snow leopard',
    18.         'Varan',
    19.         'Big panda',
    20.         'Capercaillie',
    21.         'Pheasant',
    22.         'Mantis',
    23.         'Brown bear',
    24.         'Sable',
    25.         'Wolf'
    26.     ]
    27. ];
    28.  
    29. $name_two_words = [];
    30. foreach($continents as $continent => $animals){
    31.     foreach($animals as $animal){
    32.         $all_animals= [];
    33.         $anim = explode(' ', $animal);
    34.         $all_animals[]=$anim;
    35.      
    36.         foreach($all_animals as $k){
    37.             if(count($k) === 2){
    38.                 $comma_separated = implode(",", $k);
    39.                 $str = str_replace(',', ' ', $comma_separated);
    40.                 $name_two_words[]=$str;
    41.             }
    42.         }
    43.     }
    44. }
    45.  
    46. echo '<pre>';
    47. var_dump($name_two_words);
    48. echo '<pre>';
    49.  
    50. foreach($name_two_words as $name){
    51.     $parts = explode(' ', $name);
    52.     $first[] = $parts[0];
    53.     $second[] = $parts[1];
    54. }
    55. /*
    56. echo '<pre>';
    57. var_dump($first);
    58. var_dump($second);
    59. echo '<pre>';
    60. */
    61. $random_first_word = [];
    62.  
    63. while (count($random_first_word) < count($name_two_words)){
    64.    $proverka = $first[rand(0, count($name_two_words)-1)];
    65.     if (!in_array($proverka, $random_first_word)) {
    66.         array_push($random_first_word, $proverka);
    67.     }
    68. }
    69.  
    70. //var_dump($random_first_word);
    71.  
    72. $random_second_word = [];
    73.  
    74. while (count($random_second_word) < count($name_two_words)){
    75.     $proverka = $second[rand(0, count($name_two_words)-1)];
    76.     if (!in_array($proverka, $random_second_word)) {
    77.         array_push($random_second_word, $proverka);
    78.     }
    79. }
    80.  
    81. //var_dump($random_second_word );
    82.  
    83. $final_result = [];
    84.  
    85. for($i = 0; $i < count($name_two_words); $i++){
    86.     $final_result[]= $random_first_word[$i] . ' ' . $random_second_word[$i];  
    87. }
    88.  
    89. var_dump($final_result);
    Результат, каждый раз будет другой

    До

    Код (Text):
    1. array(5) {
    2.   [0]=>
    3.   string(16) "African elephant"
    4.   [1]=>
    5.   string(13) "Spotted hyena"
    6.   [2]=>
    7.   string(12) "Snow leopard"
    8.   [3]=>
    9.   string(9) "Big panda"
    10.   [4]=>
    11.   string(10) "Brown bear"
    12. }
    После

    Код (Text):
    1. array(5) {
    2.   [0]=>
    3.   string(13) "African hyena"
    4.   [1]=>
    5.   string(8) "Big bear"
    6.   [2]=>
    7.   string(13) "Brown leopard"
    8.   [3]=>
    9.   string(16) "Spotted elephant"
    10.   [4]=>
    11.   string(10) "Snow panda"
    12. }
     
  5. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    20) Получить список всех дубликатов значений массива
    Самый быстрый способ - использовать array_diff_key().
    Но стоит помнить, что это требует много памяти.

    Пример:
    PHP:
    1. $array = [1, 10, 12, 2, 7, 3, 9, 4, 2, 7, 8, 5, 3, 7];
    2. $duplicates = array_diff_key($array,  array_flip(array_flip($array)));
    3. print_r($duplicates);
    4. /*
    5. Array (
    6.     [3] => 2
    7.     [4] => 7
    8.     [5] => 3
    9.     [9] => 7
    10. )
    11. */
    п.с. Повод для алгоритма - эта тема.

    21) Убрать дубликаты значений массива
    Самый быстрый способ - использовать array_intersect_key().
    Но стоит помнить, что это требует много памяти.

    Пример:
    PHP:
    1. $array = [1, 10, 12, 2, 7, 3, 9, 4, 2, 7, 8, 5, 3, 7];
    2. $duplicates = array_intersect_key($array,  array_flip(array_flip($array)));
    3. print_r($duplicates);
    4. /*
    5. Array (
    6.     [0] => 1
    7.     [1] => 10
    8.     [2] => 12
    9.     [6] => 9
    10.     [7] => 4
    11.     [8] => 2
    12.     [10] => 8
    13.     [11] => 5
    14.     [12] => 3
    15.     [13] => 7
    16. )
    17. */
     
    #30 Chushkin, 13 июл 2017
    Последнее редактирование: 13 июл 2017
  6. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    22) Дан массив с числами. Посчитайте суммарное количество цифр 3 в этих числах.

    PHP:
    1. $arr = [1, 55, 43, 88, 6, 5, 333, 912, 23, 9, 334, 83];
    2.     $arr2 = [3, 11, 13, 31, 28, 34];
    3.    
    4.     function countEqualNum($massiv) {
    5.         $newArr = [];
    6.         $count  = '';
    7.    
    8.         foreach($massiv as $k ) {
    9.             if(strpos($k, '3') !== false) {
    10.                 $newArr[] = $k;  
    11.             }
    12.         }
    13.        
    14.         foreach($newArr as $key ) {
    15.             $count  = $count  . $key;
    16.         }
    17.        
    18.         $count = mb_strlen(str_replace([0,1,2,4,5,6,7,8,9], [''], $count ));
    19.        
    20.         return $count;
    21.     }
    22.    
    23.    
    24.    
    25.     echo countEqualNum($arr);
    26.     echo '<br>';
    27.     echo countEqualNum($arr2);
     
  7. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
  8. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    23) Узнайте сколько дней осталось до Нового Года. Скрипт должен работать в любом году

    PHP:
    1. $date = date_create(); //текущая дата
    2.    
    3.     $datka = date_format($date, 'd.n.Y');
    4.     $newYear = 12; //последний месяц года
    5.     $arr = explode('.', $datka);
    6.    
    7.    
    8.     $month = []; //здесь будет количество дней, в каждом месяце текущего года
    9.    
    10.     for($i = 1; $i <=12; $i++) {
    11.          $month[$i] = date("t", mktime(0, 0, 0, $i, $arr[0], $arr[2]));
    12.     }
    13.    
    14.     echo '<pre>';
    15.         print_r($month);
    16.     echo '</pre>';
    17.    
    18.     $ostatok = 0;
    19.    
    20.     for($j = $arr[1]; $j <=12; $j++) { //$arr[1]отсчёт начинается с текущего месяца (складываются все дни)
    21.         $ostatok= $ostatok + $month[$j];
    22.     }
    23.    
    24.     echo 'Количество дней до Нового года: ' . ($ostatok - $arr[0]);
     
  9. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Полезность данного решения сомнительна. Это ж просто задачка тривиальная. Ты молодец, что ее решил, но это так себе лайвхак. Да и решение краааайне спорное. Зачем циклы? И, как твое предыдущее решение, тоже может быть сделано всего парой строчек кода. Завязывай в общем. Все подряд сюда не надо складывать.

    И учись работать с датой.
     
  10. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    А что не так?
     
  11. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Варианты для задачи 23:
    PHP:
    1.  idate('z', mktime(0, 0, 0, 12, 31, idate('Y'))) + 1 - idate('z');
    2. // или
    3. (int)((mktime(0, 0, 0, 1, 1, idate('Y')+1) - time()) / 86400) + 1;
    с поправкой: ...в любом году UNIX-времени.
     
    Fell-x27 нравится это.
  12. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Ответ выше. Крч, не спеши ты сюда постить, пока только учишься.
     
  13. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    на 1 день врёт
     
  14. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    24) Преобразование в римские цифры.
    PHP:
    1. function ToRomanNumerals($num, $prefix='***') {
    2.     static $cnv = [
    3.         ['','I','II','III','IV','V','VI','VII','VIII','IX'],
    4.         ['','X','XX','XXX','XL','L','LX','LXX','LXXX','XC',],
    5.         ['','C','CC','CCC','CD','D','DC','DCC','DCCC','CM',],
    6.         ['','M','MM','MMM'],
    7.     ];
    8.     $ns = strrev((int)$num);
    9.     return ($num > 3999 ? $prefix : '') . ($cnv[3][$ns{3} ?? 0] ?? '') . $cnv[2][$ns{2} ?? 0] . $cnv[1][$ns{1} ?? 0] . $cnv[0][$ns{0} ?? 0];
    Один из самых коротких и самых быстрых вариантов.
     
    [vs] нравится это.
  15. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Может и не особо короче, но побыстрее:
    PHP:
    1. <?php
    2. function int2roman($n) {
    3.     $M = ["","M","MM","MMM"];
    4.     $C = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"];
    5.     $X = ["","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"];
    6.     $I = ["","I","II","III","IV","V","VI","VII","VIII","IX"];
    7.     return $M[$n/1000].$C[($n % 1000)/100].$X[($n % 100)/10].$I[($n % 10)];
    8.     // или вместо конкатенации
    9.     // return sprintf('%s%s%s%s', $M[$n/1000],$C[($n % 1000)/100],$X[($n % 100)/10],$I[($n % 10)]);
    10. }
    11. echo int2roman(2019);
     
    #40 Deonis, 18 мар 2019
    Последнее редактирование: 18 мар 2019
  16. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
  17. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    26) Число вторников между датами.
    PHP:
    1. $delta = strtotime($data_upto .' tuesday next week - 1 week') -
    2.          strtotime($data_from .' tuesday');
    3. $count = intdiv($delta, 604800) + 1; // число вторников
    Пример:
    PHP:
    1. $data_from = '2020-01-01';
    2. $data_upto = '2020-03-31';
    3. $delta = strtotime($data_upto .' tuesday next week - 1 week') -
    4.          strtotime($data_from .' tuesday');
    5. $count = intdiv($delta, 604800) + 1; // число вторников
    6. var_dump($count); // int(13)
     
    romach и [vs] нравится это.
  18. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    27) Из HEX-строки получить "printable"-строку.
    PHP:
    1. function HexToPrintable($hex) {
    2.     return preg_replace_callback('/=(.{2})/',
    3.         function($matches) { return '\x' . strtolower($matches[1]); },
    4.         quoted_printable_encode(hex2bin($hex)));
    5.  
    6. }
    Пример:
    PHP:
    1. print_r([HexToPrintable('2cd2d948cfaf4b1097530f7c74fb6737'), ',\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7']);
    2. /*
    3. Array
    4. (
    5.     [0] => ,\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7
    6.     [1] => ,\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7
    7. )
    8. */
     
    Deonis нравится это.
  19. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    28) Получить город из адреса
    Алгоритм. Т.к. адрес это список с разделителями в виде запятых, то:
    1. Найти элемент списка с одиночной буквой "г";
    2. Удалить "г" или "г.";
    3. Удалить начальные и конечные пробелы

    Пример:
    PHP:
    1. // Просто список адресов
    2. $addresses = explode("\n",
    3. 'Республика Карелия, Беломорский район, г. Беломорск, Мерецкова улица, 6
    4. Ханты-Мансийский автономный округ - Югра, 628616, г Нижневартовск, ул Менделеева,
    5. Республика Крым, 298302, Крым Респ, Керчь г, Жени Дудник ул, дом 1
    6. Республика Татарстан, г. Набережные Челны, Моторная улица
    7. Город-1 г, Моторная улица
    8. Город-2 г
    9. Республика, г. Город3');
    10.  
    11. $cities = preg_replace([
    12.     '/.*(?:,|^)(.*?\bг\b.*?)(?:,|$).*/ui',
    13.     '/г[\.]*/u',
    14.     '/^\s+|\s+$/u'],
    15.     '$1',
    16.     $addresses);
    17.  
    18. print_r($cities);
    19. /* Array
    20. (
    21.   [0] => Беломорск
    22.   [1] => Нижневартовск
    23.   [2] => Керчь
    24.   [3] => Набережные Челны
    25.   [4] => Город-1
    26.   [5] => Город-2
    27.   [6] => Город3
    28. ) */
     
  20. miltorg

    miltorg Активный пользователь

    С нами с:
    7 апр 2019
    Сообщения:
    375
    Симпатии:
    12
    Адрес:
    Калининград
    PHP:
    1. $n=new DateTime('now');
    2. $n31 = new DateTime('last day of december this year');
    3.  
    4. $interval=$n->diff($n31);
    5. echo $interval->format('%r%a');
     
  21. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    29) Найти общие части слов.

    PHP:
    1. function GetCommonParts(array $source) {
    2.     $parts = [];
    3.     foreach($source as $k => $v) {
    4.         $symbols = mb_str_split(mb_strtolower($v));
    5.         for($i = mb_strlen($v); $i > 0; $i--) {
    6.             $kk = '';
    7.             foreach(array_slice($symbols, -$i) as $symbol) {
    8.                 $kk .= $symbol;
    9.                 $parts[$k][$kk] = null;
    10.             }
    11.         }
    12.     }
    13.     return $parts ? array_keys(array_intersect_key(...$parts)) : [];
    14. }
    Пример:

    PHP:
    1. $words = ['волк', 'восток', 'волейбол']; // Всего:: 67 частей.
    2. print_r(GetCommonParts($words));
    3. /*
    4. Array (
    5.     [0] => в
    6.     [1] => во
    7.     [2] => о
    8. )
    9. */
    Скорость выполнения: порядка 0.0000003 сек/часть

    * Задача и исходные данные из той темы.
     
  22. ibnteo

    ibnteo Активный пользователь

    С нами с:
    30 сен 2008
    Сообщения:
    34
    Симпатии:
    1
    Поменять значения двух переменных местами (Swap):
    PHP:
    1. list ($v2, $v1) = [$v1, $v2];
    Поменять значения трёх переменных местами (Rot):
    PHP:
    1. list ($v2, $v3, $v1) = [$v1, $v2, $v3];
     
  23. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.108
    Симпатии:
    1.243
    Адрес:
    там-сям
    @ibnteo Не знаю с какой версии так, но в PHP 7.4+ можно просто [$v2, $v3, $v1] = [$v1, $v2, $v3]
     
    ibnteo нравится это.
  24. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    920
    Симпатии:
    143
    >= 7.1
    Да, любители они добавлять синтаксиса без смены мажорной версии.
     
    ibnteo нравится это.