Advertisement
Guest User

Untitled

a guest
Dec 18th, 2021
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 3.12 KB | None | 0 0
  1. class Parser {
  2.     private string $bits;
  3.     private int $pointer;
  4.  
  5.     public function __construct(string $bits)
  6.     {
  7.         $this->bits = $bits;
  8.         $this->pointer = 0;
  9.     }
  10.  
  11.     public function read(int $length): string
  12.     {
  13.         $buffer = substr($this->bits, $this->pointer, $length);
  14.         $this->pointer += $length;
  15.         return $buffer;
  16.     }
  17.  
  18.     public function parse(): Packet
  19.     {
  20.         $version = bindec($this->read(3));
  21.         $type = bindec($this->read(3));
  22.         if ($type === 4) return new Packet($version, $type, $this);
  23.         return new OpPacket($version, $type, $this);
  24.     }
  25.  
  26.     public function getPointer(): int
  27.     {
  28.         return $this->pointer;
  29.     }
  30. }
  31.  
  32. class Packet {
  33.     protected int $version;
  34.     protected int $type;
  35.     private string $value;
  36.  
  37.     public function __construct(int $version, int $type, Parser $parser)
  38.     {
  39.         $this->version = $version;
  40.         $this->type = $type;
  41.         $this->value = '';
  42.         $this->readPacket($parser);
  43.      }
  44.  
  45.     public function readPacket(Parser $parser): void
  46.     {
  47.         do {
  48.             $flag = $parser->read(1);
  49.             $this->value .= $parser->read(4);
  50.         } while ($flag > 0);
  51.     }
  52.  
  53.     public function getVersionSum(): int
  54.     {
  55.         return $this->version;
  56.     }
  57.  
  58.     public function getValue(): int
  59.     {
  60.         return bindec($this->value);
  61.     }
  62. }
  63.  
  64. class OpPacket extends Packet {
  65.     private array $subPackets = [];
  66.  
  67.     public function readPacket(Parser $parser): void
  68.     {
  69.         $lengthTypeId = intval($parser->read(1));
  70.         if ($lengthTypeId === 1) {
  71.             $qty = bindec($parser->read(11));
  72.             for ($i = 0; $i < $qty; $i++) {
  73.                 $this->subPackets[] = $parser->parse();
  74.             }
  75.         } else {
  76.             $length = bindec($parser->read(15));
  77.             $pointer = $parser->getPointer();
  78.             while ($parser->getPointer() - $pointer < $length) {
  79.                 $this->subPackets[] = $parser->parse();
  80.             }
  81.         }
  82.     }
  83.  
  84.     public function getVersionSum(): int
  85.     {
  86.         return $this->version + array_reduce($this->subPackets, fn ($versionSum, Packet $subPacket) => $versionSum + $subPacket->getVersionSum(), 0);
  87.     }
  88.  
  89.     public function getValue(): int
  90.     {
  91.         $operations = [
  92.             fn ($v) => array_sum($v),
  93.             fn ($v) => array_product($v),
  94.             fn ($v) => min($v),
  95.             fn ($v) => max($v),
  96.             fn ($v) => 0,
  97.             fn ($v) => intval($v[0] > $v[1]),
  98.             fn ($v) => intval($v[0] < $v[1]),
  99.             fn ($v) => intval($v[0] == $v[1])
  100.         ];
  101.  
  102.         $values = array_reduce($this->subPackets, fn ($values, Packet $subPacket) => array_merge($values, [$subPacket->getValue()]), []);
  103.         return $operations[$this->type]($values);
  104.     }
  105. }
  106.  
  107. $inputs = file_get_contents('input.txt');
  108. $bits = implode(array_map(fn($char) => str_pad(base_convert($char, 16, 2), 4, '0', STR_PAD_LEFT), str_split($inputs)));
  109. $parser = new Parser($bits);
  110. $packet = $parser->parse();
  111.  
  112. echo $packet->getVersionSum().PHP_EOL;
  113. echo $packet->getValue();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement