Added skip function for faster exit. Part 2 still broken
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
FILE=input
|
FILE=$1
|
||||||
# Sparse sequence
|
# Sparse sequence
|
||||||
read -r -a SPARSE_ARRAY <<< "$(
|
read -r -a SPARSE_ARRAY <<< "$(
|
||||||
INDEX=0
|
INDEX=0
|
||||||
@ -15,13 +15,13 @@ read -r -a SPARSE_ARRAY <<< "$(
|
|||||||
else
|
else
|
||||||
for (( i=1; i<=CHAR; i++ ))
|
for (( i=1; i<=CHAR; i++ ))
|
||||||
do
|
do
|
||||||
printf ". "
|
printf "%s " '-1'
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
(( INDEX++ ))
|
(( INDEX++ ))
|
||||||
done <<< "$( sed -E 's/(.)/\1\n/g' "$FILE" | grep -v '^$' )"
|
done <<< "$( sed -E 's/(.)/\1\n/g' "$FILE" | grep -v '^$' )"
|
||||||
)"
|
)"
|
||||||
printf "%s" "${SPARSE_ARRAY[@]}"
|
printf "%s" "${SPARSE_ARRAY[@]}" | fold -w 100
|
||||||
printf "\n"
|
printf "\n"
|
||||||
printf "Sparse array len: %s\n" "${#SPARSE_ARRAY[@]}"
|
printf "Sparse array len: %s\n" "${#SPARSE_ARRAY[@]}"
|
||||||
SHADOW_ARRAY=( "${SPARSE_ARRAY[@]}" )
|
SHADOW_ARRAY=( "${SPARSE_ARRAY[@]}" )
|
||||||
@ -29,72 +29,87 @@ SHADOW_ARRAY=( "${SPARSE_ARRAY[@]}" )
|
|||||||
# Start by working backwards
|
# Start by working backwards
|
||||||
j=$(( ${#SPARSE_ARRAY[@]} - 1 )) # Moveable index since file blocks jump
|
j=$(( ${#SPARSE_ARRAY[@]} - 1 )) # Moveable index since file blocks jump
|
||||||
k=0 # SHADOW_ARRAY cursor
|
k=0 # SHADOW_ARRAY cursor
|
||||||
|
LAST_SKIP=9999
|
||||||
while [[ $j -ge 0 ]]
|
while [[ $j -ge 0 ]]
|
||||||
do
|
do
|
||||||
if [[ ${SPARSE_ARRAY[j]} != '.' ]]
|
# Find a file
|
||||||
|
if [[ ${SPARSE_ARRAY[j]} -eq -1 ]]
|
||||||
then
|
then
|
||||||
|
# Not a file
|
||||||
# Get file size
|
|
||||||
FILE_SIZE=0
|
|
||||||
ID=${SPARSE_ARRAY[j]}
|
|
||||||
while [[ ${SPARSE_ARRAY[j]} == "$ID" ]]
|
|
||||||
do
|
|
||||||
(( FILE_SIZE++ ))
|
|
||||||
(( j-- ))
|
|
||||||
done
|
|
||||||
printf "File ID: %s, File size: %s\n" "$ID" "$FILE_SIZE" 2>&1
|
|
||||||
|
|
||||||
# Search for available contiguous space
|
|
||||||
# Search from start until the file itself
|
|
||||||
k=0
|
|
||||||
while [[ $k -lt $(( j - FILE_SIZE )) ]]
|
|
||||||
do
|
|
||||||
CONT_SPACE=0
|
|
||||||
|
|
||||||
# Skip ahead until first match of space
|
|
||||||
while [[ ${SHADOW_ARRAY[k]} != "." ]]
|
|
||||||
do
|
|
||||||
(( k++ ))
|
|
||||||
done
|
|
||||||
|
|
||||||
# Space found, now get contiguous length
|
|
||||||
while [[ ${SHADOW_ARRAY[k]} == '.' ]]
|
|
||||||
do
|
|
||||||
(( CONT_SPACE++ ))
|
|
||||||
(( k++ ))
|
|
||||||
done
|
|
||||||
|
|
||||||
# Space length is ok, can proceed
|
|
||||||
if [[ $FILE_SIZE -le $CONT_SPACE ]] ;then break; fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Can proceed
|
|
||||||
if [[ $FILE_SIZE -le $CONT_SPACE ]]
|
|
||||||
then
|
|
||||||
# Move the file to the contiguous space
|
|
||||||
(( k-= CONT_SPACE ))
|
|
||||||
while [[ $FILE_SIZE -gt 0 ]]
|
|
||||||
do
|
|
||||||
SHADOW_ARRAY[k]=$ID
|
|
||||||
SHADOW_ARRAY[j+FILE_SIZE]='.'
|
|
||||||
(( k++ ))
|
|
||||||
(( FILE_SIZE-- ))
|
|
||||||
done
|
|
||||||
else
|
|
||||||
# Skip the file
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
(( j-- ))
|
(( j-- ))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get file size
|
||||||
|
# j moved to index before file head
|
||||||
|
FILE_SIZE=0
|
||||||
|
ID=${SPARSE_ARRAY[j]}
|
||||||
|
while [[ ${SPARSE_ARRAY[j]} == "$ID" ]]
|
||||||
|
do
|
||||||
|
(( FILE_SIZE++ ))
|
||||||
|
(( j-- ))
|
||||||
|
done
|
||||||
|
#printf "File ID: %s, File size: %s\n" "$ID" "$FILE_SIZE" 2>&1
|
||||||
|
|
||||||
|
# Since search space is constantly decreasing
|
||||||
|
# Contiguous space can only keep getting smaller
|
||||||
|
if [[ $FILE_SIZE -ge $LAST_SKIP ]]
|
||||||
|
then
|
||||||
|
printf "File %s size %s skipped. Last skip: %s\n" "$ID" "$FILE_SIZE" "$LAST_SKIP"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Search for available contiguous space
|
||||||
|
# Search from start until the file itself
|
||||||
|
k=0
|
||||||
|
while [[ $k -le $j ]] && [[ $k -le ${#SHADOW_ARRAY[@]} ]]
|
||||||
|
do
|
||||||
|
CONT_SPACE=0
|
||||||
|
|
||||||
|
# Skip ahead until first match of space
|
||||||
|
while [[ ${SHADOW_ARRAY[k]} -ne -1 ]] && [[ $k -le ${#SHADOW_ARRAY[@]} ]]
|
||||||
|
do
|
||||||
|
(( k++ ))
|
||||||
|
done
|
||||||
|
|
||||||
|
# Space found, now get contiguous length
|
||||||
|
while [[ ${SHADOW_ARRAY[k]} -eq -1 ]] && [[ $k -le ${#SHADOW_ARRAY[@]} ]]
|
||||||
|
do
|
||||||
|
(( CONT_SPACE++ ))
|
||||||
|
(( k++ ))
|
||||||
|
done
|
||||||
|
|
||||||
|
# Space length is ok, can proceed
|
||||||
|
if [[ $FILE_SIZE -le $CONT_SPACE ]] ;then break; fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Space length ok, can proceed
|
||||||
|
if [[ $FILE_SIZE -le $CONT_SPACE ]]
|
||||||
|
then
|
||||||
|
# Move the file to head of contiguous space
|
||||||
|
(( k-= CONT_SPACE ))
|
||||||
|
while [[ $FILE_SIZE -gt 0 ]] && \
|
||||||
|
[[ ${SHADOW_ARRAY[k]} -eq -1 ]] && \
|
||||||
|
[[ ${SHADOW_ARRAY[j+FILE_SIZE]} -ne -1 ]]
|
||||||
|
do
|
||||||
|
SHADOW_ARRAY[k]=$ID
|
||||||
|
SHADOW_ARRAY[j+FILE_SIZE]=-1
|
||||||
|
(( k++ ))
|
||||||
|
(( FILE_SIZE-- ))
|
||||||
|
done
|
||||||
|
else
|
||||||
|
LAST_SKIP=$FILE_SIZE
|
||||||
|
printf "File %s skipped. File size: %s\n" "$ID" "$FILE_SIZE"
|
||||||
|
continue
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
printf "%s" "${SHADOW_ARRAY[@]}"
|
printf "%s " "${SHADOW_ARRAY[@]}" | fold -w 100 | tee final-result | cat
|
||||||
printf "\n"
|
printf "\n"
|
||||||
|
|
||||||
# Generate checksum for sparse array
|
# Generate checksum for shadow array
|
||||||
CHECKSUM=0
|
CHECKSUM=0
|
||||||
for (( i=0; i<${#SHADOW_ARRAY[@]}; i++ ))
|
for (( i=0; i<${#SHADOW_ARRAY[@]}; i++ ))
|
||||||
do
|
do
|
||||||
if [[ ${SHADOW_ARRAY[i]} != "." ]] ;then (( CHECKSUM += i * SHADOW_ARRAY[i] )); fi
|
if [[ ${SHADOW_ARRAY[i]} -ne -1 ]] ;then (( CHECKSUM += i * SHADOW_ARRAY[i] )); fi
|
||||||
done
|
done
|
||||||
printf "%s" "$CHECKSUM"
|
printf "%s\n" "$CHECKSUM"
|
||||||
|
Reference in New Issue
Block a user