Ответы пользователя по тегу PHP
  • Как расшифровать в php строчку по указанным правилам?

    @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;

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