Bash luhn exercise

I can’t figure out why this is not working:

echo "Please enter a number/string: "  #4539319503436467
  read string
   
       set -x
       array=()
       
     for (( x=${#string}-1; x >= 0; x-- ))
  
         do
  
             echo "x is:$x"
             array+={string:$x:1} # or array+=( $string:$x:1 )
                               
         done                    
  
  declare -p array

The output I’m getting:

Please enter a number/string: 
4539319503436467    
+ array=()
+ (( x=16-1 ))
+ (( x >= 0 ))
+ echo 'x is:15'
x is:15
+ array+='{string:15:1}'
+ (( x--  ))
+ (( x >= 0 ))
+ echo 'x is:14'
x is:14
+ array+='{string:14:1}'
+ (( x--  ))
+ (( x >= 0 ))
<----------SNIP------------->
declare -p array
declare -a array=([0]="{string:15:1}{string:14:1}{string:13:1}
{string:12:1}{string:11:1}{string:10:1}{string:9:1}{string:8:1}
{string:7:1}{string:6:1}{string:5:1}{string:4:1}{string:3:1}
{string:2:1}{string:1:1}{string:0:1}")

or I get the full input string: {4539319503436467:15:1}

Did you mean array+=${string:$x:1} ?

This is a tricky bit of bash syntax. array is defined to be an array.

To append to it, you need to still use parentheses

array+=( "a new element" )

Where you’re getting hung up is with the variable expansion syntax. To extract a substring starting at offset and extending for length characters, you must use this syntax, with the dollar and the braces.

${varname:offset:length}

Put that together:

array+=( "${string:$x:1}" )

The double quotes are needed here.


Bash arrays are odd. If you start to treat the variable as a plain “scalar” variable, you intract with the element at index 0

array=(11 22 33)
echo ${array[0]}   # => 11
echo $array        # => 11
array+="hello"
echo ${array[0]}   # => 11hello
echo $array        # => 11hello
declare -p array
# => declare -a array=([0]="11hello" [1]="22" [2]="33")

This exercise calls for doubling every 2nd digit of the input from the top.
So in this case using 4539319503436467 as the input, it would be 6, 6, 4, 0, 9, 3, 3, 4

I can’t get my head around how to do this. I’m thinking something like this:

echo "Please enter a number/string: " #input-4539319503436467
read string

for (( x=${#string}; x >= 0; x-- ))
 
         do
  
             if [[ x is in the 2nd position ]] 
  
                then
                      $temp=$x
                      $temp*2
  
             fi

Any suggestions?

Typically you’d check if a number is even or odd by using the var % 2 operator. “2nd position” means its index is one or the other of those.