0

I'm just learning to code with bash, and I'm running into some problems doing some exercises. I feel like I might be doing something wrong with the syntax, but no matter how I look at it it doesn't look wrong.

The code I've got here is supposed to find the 'lucky numbers' between 1000 and 10000. In this case, a lucky number is a number who's digits sum to a number that in turns sums to 7. The part that does the calculation of the lucky number works on it's own, but once I put it into a for loop, where there is no single input, the output is infinite and wrong. I can only assume the for loop is the problem:

digit=0
sum=0
for (( i=1000; i<=10000; i++ ))
do
     while [ $i -gt 0 ]
     do
          digit=$(( $i % 10 ))
          i=$(( $i / 10 ))
          sum=$(( $sum + $digit ))
    done
    while [ $sum -gt 0 ]
    do
          digit=$(( $sum % 10 ))
          sum$(( $sum / 10 ))
          sum2=$(( $sum2 + $digit ))
    done
    if [[ $sum2 == 7 ]];
    then
          echo $sum2
    fi
done

If anyone has any idea what I'm doing wrong, or even a way to make it better, I would really appreciate it!

6
  • 1
    What is the intended meaning of this line: sum$(( $sum ? 10 )). I'm assuming that's a copy/paste error. Commented Nov 15, 2016 at 1:20
  • 1<=10000 is always true. Commented Nov 15, 2016 at 1:21
  • 2
    A good question isolates a single, specific problem, and removes everything but the minimum amount of code needed to demonstrate that problem. See sscce.org or stackoverflow.com/help/mcve Commented Nov 15, 2016 at 1:22
  • 1
    You're also changing i inside the loop, which is generally a bad idea. Commented Nov 15, 2016 at 1:22
  • Yeah... @kaitoy is right. It should be i<=10000. Commented Nov 15, 2016 at 1:22

2 Answers 2

1
i=$(( $i / 10 ))

You're modifying the for loop's variable. Don't do that; make a copy.

Sign up to request clarification or add additional context in comments.

Comments

1

for (( i=1000; i<=10000; i++ ))

If you want to learn bash for bash's sake, every last nook and cranny, that's fine, but I suggest you focus your attention on portable Bourne shell syntax.

  • It works in bash, and it has worked for millions of programmers for decades. Very often, the Old Ways are good ways.

  • You will encounter non-bash code in a variety of circumstances.

Most Linux systems include seq(1). So these work:

$ for i in $(seq 1000 10000); do echo $i; done | wc -l
9001
$ seq 1000 10000 | while read i; do echo $i; done | wc -l
9001

Shell scripts usually iterate over some input (a list of filenames, say) not for N times. I guess seq was invented to support counted loops before bash developed the counted-loop syntax.

As a by-product of using seq, I think your loop body will work unaltered. Because the loop (while or for) is assigning i from its input from seq, whatever you do to i in the body is lost at the next iteration.

1 Comment

You could also for i in {1000..10000}; do ....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.