Задать вопрос
@legatobrown

Как расшифровать в php строчку по указанным правилам?

Расшифровать шифр ->11гe+20∆∆A+4µcњil->5•Ћ®†Ѓ p+5f-7Ќ¬f pro+10g+1悦ra->58->44m+1*m+2a喜er!

Правила его расшифровки следующие:

- Начинать чтение нужно с крайнего левого символа и двигаться вправо.
- Если вы сталкиваетесь с любым символом, кроме специальных обозначений, то данный символ без изменений попадает в результирующую строчку.
- Специальными обозначениями являются "->", "+", "-". После специального обозначения всегда идет число, являющееся аргументом.
- "->" — вам необходимо перейти к символу с номером, записанном в аргументе (счет начинается с 0).
- "+" — пропустить столько символов, сколько записано в аргументе. Отсчет начинается после аргумента.
- "-" — аналогично, но перемещение происходит назад (влево)

Ответом является строчка.
  • Вопрос задан
  • 484 просмотра
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Skillfactory
    Профессия Fullstack веб-разработчик на JavaScript и PHP
    20 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 1
@Uinit
Как-то так:
<?php declare(strict_types=1);

$input = '->11гe+20∆∆A+4µcњil->5•Ћ®†Ѓ p+5f-7Ќ¬f pro+10g+1悦ra->58->44m+1*m+2a喜er!';

class Decoder
{
    private $position   = 0;
    private $output     = '';

    private $state;

    private const STATE_FREE        = 'processFree';
    private const STATE_MINUS       = 'processMinus';
    private const STATE_READ_NUMBER = 'processReadNumber';

    private const METHOD_GO         = 'goStack';
    private const METHOD_SKIP_RIGHT = 'skipStackRight';
    private const METHOD_SKIP_LEFT  = 'skipStackLeft';

    private $stack;
    private $method;

    public function decode(string $input): string
    {
        $this->position = 0;
        $this->output   = '';
        $this->state    = self::STATE_FREE;

        $length = mb_strlen($input, 'UTF-8');

        while ($this->position < $length){
            $symbol = mb_substr($input, $this->position, 1, 'UTF-8');
            $this->{$this->state}($symbol);
        }

        return $this->output;
    }

    private function processFree(string $symbol): void
    {
        switch ($symbol){
            case '-':
                $this->state = self::STATE_MINUS;
                break;
            case '+':
                $this->method = self::METHOD_SKIP_RIGHT;
                $this->state = self::STATE_READ_NUMBER;
                break;
            default:
                $this->output .= $symbol;
                break;
        }

        $this->position++;
    }

    private function processMinus(string $symbol): void
    {
        if($symbol === '>'){
            $this->method   = self::METHOD_GO;
            $this->state    = self::STATE_READ_NUMBER;
            $this->position++;
            return;
        }

        $this->method = self::METHOD_SKIP_LEFT;
        $this->state = self::STATE_READ_NUMBER;
    }

    private function processReadNumber(string $symbol): void
    {
        if($this->isNumber($symbol)){
            $this->stack .= $symbol;
            $this->position++;
            return;
        }

        if($this->stack === null){
            throw new \InvalidArgumentException('Method has\'t number argument at position: '.$this->position);
        }

        $this->{$this->method}((int)$this->stack);
        $this->stack    = null;
        $this->method   = null;
        $this->state    = self::STATE_FREE;

    }

    private function isNumber(string $symbol): bool
    {
        return !!preg_match('#[0-9]#',$symbol);
    }

    private function goStack(int $arg): void
    {
        $this->position = $arg;
    }

    private function skipStackRight(int $arg): void
    {
        $this->position += $arg;
    }

    private function skipStackLeft(int $arg): void
    {
        $this->position -= $arg;
    }
}


$out = (new Decoder())->decode($input);
echo $out;

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

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽