Skip to content

Instantly share code, notes, and snippets.

@dimabory
Created November 6, 2018 17:08
Show Gist options
  • Save dimabory/13c7e92c50d9ef2fa8caaf5051265da3 to your computer and use it in GitHub Desktop.
Save dimabory/13c7e92c50d9ef2fa8caaf5051265da3 to your computer and use it in GitHub Desktop.
pikabu interview
<?php
/*
14. Напишите, пожалуйста, код для сортировки массива $arr по полю id. Структура массива:
$arr = [
['id' => 1, ...],
['id' => 2, ...],
['id' => 3, ...],
...
];
*/
$arr = [
['id' => 16],
['id' => 22],
['id' => 13],
['id' => 3],
['id' => 53],
['id' => 1],
];
usort(
$arr,
function ($a, $b) {
[$aId, $bId] = [$a['id'] ?? 0, $b['id'] ?? 0];
if ($aId === $bId) {
return 0;
}
return ($aId < $bId) ? -1 : 1;
}
);
var_dump($arr);
<?php
/*
15. Есть переменная $url, которая содержит URL вида http://pikabu.ru/2018/01/dd/text.
Необходимо написать код валидации этой переменной, используя одно регулярное выражение, по средующим критериям:
- dd - двузначное число в месяце;
- text - произвольный текст длиной от 1 до 20 символов, в котором допустимы только латинские символы нижнего регистра, нижнее подчеркивание _ и точка .;
- ссылка может иметь произвольный поддомен латинскими буквами от 3 до 10 символов, например http://www.pikabu.ru;
- протокол может быть как http, так и https.
*/
$re = '/^https?:\/\/(?:www\.)?[a-z]{3,10}\.ru\/2018\/01\/(0[1-9]|1[012])\/[a-z_\.]{3,10}$/';
<?php
/*
16. Дана строка $str с произвольным текстом (1 символ - 1 байт). Необходимо без использования циклов и рекурсий подсчитать количество символов в этой строке, у которых ascii код кратен 3.
*/
$str = 'hello world';
$result = array_reduce(
str_split($str),
function ($carry, $char) {
$code = \ord($char);
return $code % 3 === 0 && $code !== 0 ? ++$carry : $carry;
}
);
echo $result;
/*
17. Необходимо сформировать SQL запрос к таблице user_marks, который выводит количество человек по возрасту, полу и наличию/отсутствию хорошей оценки (хорошая оценка = 5).
Формат вывода: age, gender, is_positive_mark, cnt, где:
- is_positive_mark = 1 если оценка mark = 5, 0 - оценка меньше 5;
- cnt - количество записей.
Результаты нужно отсортировать по возрасту age и is_positive_mark в обратном порядке. А также необходимо выводить только группы, где количество записей cnt больше 1.
CREATE TABLE `user_marks` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`age` int(11) DEFAULT NULL,
`gender` tinyint(1) DEFAULT '0' COMMENT '0 - male, 1 - female',
`mark` int(11) DEFAULT NULL COMMENT '1-5',
PRIMARY KEY (`id`)
)
*/
SELECT um.age, um.gender, CASE WHEN um.mark = 5 THEN 1 ELSE 0 END is_positive_mark, count(*) cnt
FROM user_marks um
GROUP BY um.age, um.gender, is_positive_mark
HAVING cnt > 1
ORDER BY age DESC, is_positive_mark DESC;
<?php
/*
18. Напишите, пожалуйста, реализацию функции calc для представленного ниже кода
*/
$sum = function ($a, $b) {
return $a + $b;
};
function calc($arg)
{
static $args = [];
if (is_int($arg)) {
$args [] = $arg;
return function ($arg) {
return calc($arg);
};
}
if (is_callable($arg) || function_exists($arg)) {
$result = 0;
for ($i = 0, $count = \count($args); $i < $count; $i += 2) {
$isLast = !isset($args[$i + 1]);
$result += call_user_func($arg, ...[$isLast ? 0 : $args[$i], !$isLast ? $args[$i + 1] : $args[$i]]);
}
$args = null;
return $result;
}
throw new \InvalidArgumentException("Invalid argument: ${$arg}");
}
echo calc(2)(3)('pow'); //8
echo PHP_EOL;
echo PHP_EOL;
echo calc(5)(3)(2)($sum); //10
echo PHP_EOL;
echo calc(1)(2)($sum);//3
echo PHP_EOL;
echo calc(10)(10)(10)(10)(10)($sum);//30
echo PHP_EOL;
<?php
/*
19. В указанном ниже коде закралась ошибка, приводящая к неверному результату. Также, сам код явно нуждается в улучшении :)
Предложите, пожалуйста, исправленный и улушенный вариант этого кода.
*/
define('IS_USER_BANNED_RATE', 10);
function isUserBan(array $arr, $rate = IS_USER_BANNED_RATE)
{
return array_sum($arr) >= (float)$rate;
}
$users = [
'user1' => [1, 4.1, 3.3, 1.12],
'user2' => [2, 4.1, 8, 0.2],
'user3' => [2, 4.2, 9, 12],
];
$maxValue = IS_USER_BANNED_RATE + 4.3;
foreach ($users as $k => $v) {
echo $k.' is '.(isUserBan($v, $maxValue) ? 'banned' : 'not banned').PHP_EOL;
}
<?php
/*
20. Так вышло, что вам достался фрагмент кода, написанный гик-злодеем. Необходимо его максимально успросить: убрать и упростить лишние конструкции и выражения так, чтобы логика работы функции не поменялась.
function calc($a) {
$a = ($a & 0x3f) + 1.9 >> 0;
$c = !1 !== !!+$a ? --$a : $a++ ? ~~$a : $a++;
if (!$c == false) {
for ($a -=- ($c * 3), $c = $a; $a < $c << 0b10;) {
$a *= $c;
}
return 0 | (int)$a;
} else {
return 0 | sqrt($c);
}
}
*/
function calc($a)
{
$a = ($a & 63) + 1;
--$a;
$i = ($a += $a * 3);
do {
$a *= $i;
} while ($a < $i++ << 2);
return $a;
}
echo PHP_EOL;
echo calc(-1);
echo PHP_EOL;
echo calc(0);
echo PHP_EOL;
echo calc(1);
echo PHP_EOL;
echo calc(2);
echo PHP_EOL;
echo calc(3);
echo PHP_EOL;
echo calc(4);
echo PHP_EOL;
echo calc(5);
<?php
/*
21. Предложите способ упаковки следующих данных о пользователе с самым компактным результатом (бинарный результат допускается):
$isAdmin = false;
$isModerator = true;
$isApproved = false;
$gender = 1; // возможные значения: 0, 1, 2
$showAdultContent = false;
*/
$isAdmin = false;
$isModerator = true;
$isApproved = false;
$gender = 1;
$showAdultContent = false;
$binary = pack('i*', ...[$isAdmin, $isModerator, $isApproved, $gender, $showAdultContent]);
var_dump($binary);
var_dump(unpack('i*', $binary));
<?php
/*
22. Ниже представлен фрагмент кода, использующего класс Users:
$foo = new Users;
$foo[] = 'Guest #' . count($foo);
$foo[] = 'Guest #' . count($foo);
echo $foo;
unset($foo);
Если выполнить этот код, то в stdout напечатается следующее:
Welcome Guest #0
Welcome Guest #1
Total users: 2
Goodby Guest #0, Guest #1
*/
class Users extends \ArrayObject
{
private $collection = [];
public function offsetSet($index, $newval)
{
$this->collection [] = $newval;
echo 'Welcome '.$newval.PHP_EOL;
}
public function count()
{
return \count($this->collection);
}
public function __toString()
{
return "Total users: {$this->count()}";
}
public function __destruct()
{
echo PHP_EOL.'Goodby '.implode(', ', $this->collection);
}
}
$foo = new Users;
$foo[] = 'Guest #'.count($foo);
$foo[] = 'Guest #'.count($foo);
echo $foo;
unset($foo);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment