#!/bin/bash read input input=( $(sed 's/\(.\)/ \1 /g' <<< $input) ) bits=() cursor=0 registers=() for input_char in ${input[@]}; do case $input_char in '0') bits+=( 0 0 0 0 ) ;; '1') bits+=( 0 0 0 1 ) ;; '2') bits+=( 0 0 1 0 ) ;; '3') bits+=( 0 0 1 1 ) ;; '4') bits+=( 0 1 0 0 ) ;; '5') bits+=( 0 1 0 1 ) ;; '6') bits+=( 0 1 1 0 ) ;; '7') bits+=( 0 1 1 1 ) ;; '8') bits+=( 1 0 0 0 ) ;; '9') bits+=( 1 0 0 1 ) ;; 'A') bits+=( 1 0 1 0 ) ;; 'B') bits+=( 1 0 1 1 ) ;; 'C') bits+=( 1 1 0 0 ) ;; 'D') bits+=( 1 1 0 1 ) ;; 'E') bits+=( 1 1 1 0 ) ;; 'F') bits+=( 1 1 1 1 ) ;; esac done function parse_packet() { local version=$((2#${bits[$((cursor))]}${bits[$((cursor+1))]}${bits[$((cursor+2))]})) local packet_type=$((2#${bits[$((cursor+3))]}${bits[$((cursor+4))]}${bits[$((cursor+5))]})) cursor=$((cursor+6)) case $packet_type in '4') local binary_value='2#' local end_reached=0 while [ $end_reached -eq 0 ]; do if [ ${bits[$cursor]} -eq 0 ]; then end_reached=1 fi local binary_block=${bits[@]:$((cursor+1)):4} binary_value=$binary_value${binary_block// /} cursor=$((cursor+5)) done registers+=( $((binary_value)) ) ;; *) local length_type=${bits[$cursor]} cursor=$((cursor+1)) if [ $length_type -eq 0 ]; then local subpackets_length_arr=${bits[@]:$cursor:15} local subpackets_length=$((2#${subpackets_length_arr// /})) cursor=$((cursor+15)) local curr_cursor=$cursor local i while [ $cursor -lt $((curr_cursor+subpackets_length)) ]; do parse_packet i=$((i+1)) done else local subpackets_num_arr=${bits[@]:$cursor:11} local subpackets_num=$((2#${subpackets_num_arr// /})) local i cursor=$((cursor+11)) for ((i=0;i=-i; j--)); do result=$((result+registers[-1])) unset registers[-1] done ;; '1') local result=1 for ((j=-1; j>=-i; j--)); do result=$((result*registers[-1])) unset registers[-1] done ;; '2') local result=${registers[-1]} unset registers[-1] for ((j=-2; j>=-i; j--)); do if [ ${registers[-1]} -lt $result ]; then result=${registers[-1]} fi unset registers[-1] done ;; '3') local result=${registers[-1]} unset registers[-1] for ((j=-2; j>=-i; j--)); do if [ ${registers[-1]} -gt $result ]; then result=${registers[-1]} fi unset registers[-1] done ;; '5') if [ ${registers[-2]} -gt ${registers[-1]} ]; then local result=1 else local result=0 fi unset registers[-1] unset registers[-1] ;; '6') if [ ${registers[-2]} -lt ${registers[-1]} ]; then local result=1 else local result=0 fi unset registers[-1] unset registers[-1] ;; '7') if [ ${registers[-2]} -eq ${registers[-1]} ]; then local result=1 else local result=0 fi unset registers[-1] unset registers[-1] ;; esac registers+=( $result ) ;; esac } parse_packet echo $registers