Working part 2. Added check_tail for digit matching.

This commit is contained in:
2024-12-18 12:13:16 +08:00
parent de2fd03c3c
commit 0d518e1691
2 changed files with 64 additions and 18 deletions

View File

@ -3,7 +3,8 @@
adv () { # OPCODE 0 adv () { # OPCODE 0
$DEBUG && printf "OPCODE : 0 OP: adv OPERAND: %s\n" "$1" >&2 $DEBUG && printf "OPCODE : 0 OP: adv OPERAND: %s\n" "$1" >&2
OPERAND=$( get_combo "$1" ) OPERAND=$( get_combo "$1" )
REG_A=$(( REG_A / (2 ** OPERAND) )) #REG_A=$(( REG_A / (2 ** OPERAND) ))
REG_A=$( printf "%s / (2 ^ %s) \n" "$REG_A" "$OPERAND" | bc )
} }
bxl () { # OPCODE 1 bxl () { # OPCODE 1
$DEBUG && printf "OPCODE : 1 OP: bxl OPERAND: %s\n" "$1" >&2 $DEBUG && printf "OPCODE : 1 OP: bxl OPERAND: %s\n" "$1" >&2
@ -38,12 +39,14 @@ out () { # OPCODE 5
bdv () { # OPCODE 6 bdv () { # OPCODE 6
$DEBUG && printf "OPCODE : 6 OP: bdv OPERAND: %s\n" "$1" >&2 $DEBUG && printf "OPCODE : 6 OP: bdv OPERAND: %s\n" "$1" >&2
OPERAND=$( get_combo "$1" ) OPERAND=$( get_combo "$1" )
REG_B=$(( REG_A / (2 ** OPERAND) )) #REG_B=$(( REG_A / (2 ** OPERAND) ))
REG_B=$( printf "%s / (2 ^ %s) \n" "$REG_A" "$OPERAND" | bc )
} }
cdv () { # OPCODE 7 cdv () { # OPCODE 7
$DEBUG && printf "OPCODE : 7 OP: cdv OPERAND: %s\n" "$1" >&2 $DEBUG && printf "OPCODE : 7 OP: cdv OPERAND: %s\n" "$1" >&2
OPERAND=$( get_combo "$1" ) OPERAND=$( get_combo "$1" )
REG_C=$(( REG_A / (2 ** OPERAND) )) #REG_C=$(( REG_A / (2 ** OPERAND) ))
REG_C=$( printf "%s / (2 ^ %s) \n" "$REG_A" "$OPERAND" | bc )
} }
# Get combo operand # Get combo operand
@ -78,7 +81,22 @@ get_combo () {
# Check if the program is a quine # Check if the program is a quine
check_quine () { check_quine () {
for (( i=0; i<INPUT_LEN; i++ )) $DEBUG && printf "%s," "${INPUT[@]}"
$DEBUG && printf "%s," "${OUTPUT[@]}"
for (( i=0; i<${#INPUT[@]}; i++ ))
do
if [[ ${INPUT[$i]} != "${OUTPUT[$i]}" ]]
then
return 1
fi
done
}
# Check digits
check_tail () {
$DEBUG && printf "%s," "${INPUT[@]}"
$DEBUG && printf "%s," "${OUTPUT[@]}"
for (( i=${#INPUT[@]}; i>=${#INPUT[@]}-$1; i-- ))
do do
if [[ ${INPUT[$i]} != "${OUTPUT[$i]}" ]] if [[ ${INPUT[$i]} != "${OUTPUT[$i]}" ]]
then then
@ -125,3 +143,18 @@ read_opcode () {
(( POINTER+=2 )) (( POINTER+=2 ))
fi fi
} }
execute_machine () {
POINTER=0
while [[ $POINTER -lt $INPUT_LEN ]]
do
OPCODE=${INPUT[$POINTER]}
OPERAND=${INPUT[$POINTER+1]}
read_opcode "$OPCODE" "$OPERAND"
$DEBUG && printf "Registers A : %s B: %s C : %s\n" "$REG_A" "$REG_B" "$REG_C" >&2
$DEBUG && printf "Pointer : %s\n" "$POINTER" >&2
(( MACHINE_ITER-- ))
if [[ $MACHINE_ITER -eq 0 ]] ; then break ; fi
done | paste -s -d " "
}

View File

@ -1,31 +1,44 @@
#!/usr/bin/env bash #!/usr/bin/env bash
FILE=$1 FILE=$1
ITER=99 ITER=1
MACHINE_ITER=999
DEBUG=false DEBUG=false
INCREMENT=1
TAIL_NUM=16
REG_A=$(grep 'Register A:' "$FILE" | cut -f2 -d: ) REG_A=$(grep 'Register A:' "$FILE" | cut -f2 -d: )
REG_B=$(grep 'Register B:' "$FILE" | cut -f2 -d: ) REG_B=$(grep 'Register B:' "$FILE" | cut -f2 -d: )
REG_C=$(grep 'Register C:' "$FILE" | cut -f2 -d: ) REG_C=$(grep 'Register C:' "$FILE" | cut -f2 -d: )
#REG_A=100000000000000
REG_A=164541160582800
read -r -a INPUT <<< "$(grep 'Program:' "$FILE" | cut -f2 -d: | tr ',' ' ' )" read -r -a INPUT <<< "$(grep 'Program:' "$FILE" | cut -f2 -d: | tr ',' ' ' )"
INPUT_LEN=${#INPUT[@]} INPUT_LEN=${#INPUT[@]}
printf "Registers A: %s B: %s C: %s\n" "$REG_A" "$REG_B" "$REG_C" >&2 printf "Registers A: %s B: %s C: %s\n" "$REG_A" "$REG_B" "$REG_C" >&2
printf "Input : " >&2 #printf "Input: " >&2
printf "%s " "${INPUT[@]}" >&2 #printf "%s " "${INPUT[@]}" >&2
printf "\n" >&2 #printf "\n" >&2
# Load machine operations # Load machine operations
. machine.sh . machine.sh
POINTER=0 #while ! check_quine
while [[ $POINTER -lt $INPUT_LEN ]] while ! check_tail "$TAIL_NUM"
do do
OPCODE=${INPUT[$POINTER]} read -r -a OUTPUT <<< "$( execute_machine )"
OPERAND=${INPUT[$POINTER+1]} printf "Register A: %s\n" "$REG_A"
read_opcode "$OPCODE" "$OPERAND" printf "Output:\t"
printf "Registers A : %s B: %s C : %s\n" "$REG_A" "$REG_B" "$REG_C" >&2 #printf "%s " "${OUTPUT[@]}"
printf "Pointer : %s\n" "$POINTER" >&2 for i in "${OUTPUT[@]}"
(( ITER-- )) do
printf "%s " "$i" # Print octal representation
done
printf "\n"
printf "Input:\t"
printf "%s " "${INPUT[@]}"
printf "\n"
(( REG_A+=INCREMENT))
#(( ITER-- ))
if [[ $ITER -eq 0 ]] ; then break ; fi if [[ $ITER -eq 0 ]] ; then break ; fi
done | paste -s -d "," done