I can't figure this one out

vefatica

Here (below) is a BTM to answer a math question from the folklore (question at the end). It doesn't work because I can't get past the marked like. Whenever I reach it (first time when count == 1601) I get
Code:
``TCC: V:\number.btm   Syntax error "10*n+g"``
At that time, BDEBUGGER tells me n = 123252 and g = 1 (which are OK).

News flash! ... It works if, in that line only, I use "%n" instead of "n" (and it arrives at the right answer).

I don't get it. This must be a very obscure bug (or I'm missing something utterly obvious).

Code:
``````set count=0
do a=1 to 9 by 2
do b=2 to 8 by 2
do c=1 to 9 by 2
do d=2 to 8 by 2
do f=2 to 8 by 2
do g=1 to 9 by 2
do h=2 to 8 by 2
do i=1 to 9 by 2
set /a count+=1
set bcontinue=0
set /a n=100*a+10*b+c
if %@eval[n MOD 3] NE 0 iterate
set /a n=10*n+d
if %@eval[n MOD 4] NE 0 iterate
set /a n=100*n+50+f
if %@eval[n MOD 6] NE 0 iterate
set /a n=10*n+g & REM <===================== this line
if %@eval[n MOD 7] NE 0 iterate
set /a n=10*n+h
if %@eval[n MOD 8] NE 0 iterate
set /a n=10*n+i
if %@eval[n MOD 9] NE 0 iterate
do z=1 to 9
if %@index[%n,%z] == -1 (set bcontinue=1 & leave)
enddo
if %bcontinue == 1 iterate
echo %n
enddo
enddo
enddo
enddo
enddo
enddo
enddo
enddo``````
The question: Find a 9-digit number which uses each of 1, 2, ..., 9 exactly once, and has the property that, for i=1 to 9, the number comprising its left-hand i digits is divisible by i. The answer is unique.

vefatica

If I comment the line before the troublesome one, I get no errors (and no answer).

If I replace the line before
Code:
``if %@eval[n MOD 6] NE 0 iterate``
with
Code:
``if %@eval[6*(n\6)] != %n iterate``
(an equivalent test) I avoid the error and get the right answer.

vefatica

Boiled down: It's got something to do with the letter 'g'. Compare the last two of these:
Code:
``````v:\> set n=0

v:\> set g=0

v:\> set z=0

v:\> set /a n=z
0

v:\> set /a n=g
TCC: Syntax error "g"``````
I don't know if it's relevant, but MAPM_SET.C has a buggy routine for validating a string (as a number). More on that if desired.

vefatica

Try this;
Code:
``set /a n=(10*n+g)``
This returned an answer of 381654729

Joe
Yes, adding parentheses fixes it. I don't know why.
Code:
``````v:\> set n=0

v:\> set g=0

v:\> set /a n=g
TCC: Syntax error "g"

v:\> set /a n=(g)
0``````

rconn

Some single characters have a special meaning within the expression analyzer.

I am removing all of the (undocumented and unsupported) functionality in SET /A that isn't supported in CMD. (I.e., floating point, functions, hex numbers, binary numbers, rotates, etc.) in the next build, so if you're using strictly CMD syntax these issues won't arise any longer. If you're not using CMD syntax, you shouldn't be using SET /A.

vefatica

Some single characters have a special meaning within the expression analyzer.

I am removing all of the (undocumented and unsupported) functionality in SET /A that isn't supported in CMD. (I.e., floating point, functions, hex numbers, binary numbers, rotates, etc.) in the next build, so if you're using strictly CMD syntax these issues won't arise any longer. If you're not using CMD syntax, you shouldn't be using SET /A.
Hmmm! It's been as it is for ... how many years? I thought you didn't like breaking people's batch files. I doubt I'll be the only one.

rconn

Hmmm! It's been as it is for ... how many years? I thought you didn't like breaking people's batch files. I doubt I'll be the only one.
And I've told you for the last umpteen years not to do that.

I have to make the change because the current (undocumented + unsupported + strongly discouraged) behavior is breaking CMD compatibility.

vefatica

As a matter of fact, the line in question,
Code:
``set /a n=10*n+g``
conforms to the the rules mentioned in CMD's "SET /?" and it works in CMD.
Code:
``````C:\Users\vefatica> ver

Microsoft Windows [Version 6.1.7601]

C:\Users\vefatica> set n=2

C:\Users\vefatica> set g=5

C:\Users\vefatica> set /a n=10*n+g
25``````

vefatica

Some single characters have a special meaning within the expression analyzer.

I am removing all of the (undocumented and unsupported) functionality in SET /A that isn't supported in CMD. (I.e., floating point, functions, hex numbers, binary numbers, rotates, etc.) in the next build, so if you're using strictly CMD syntax these issues won't arise any longer. If you're not using CMD syntax, you shouldn't be using SET /A.
Will that remove the need for characters with special meaning? The 'g' is the problem, even with @EVAL.
Code:
``````v:\> set n=2

v:\> set g=5

v:\> set n=%@eval[10*n+g]
TCC: Syntax error "10*n+g"``````

rconn

Will that remove the need for characters with special meaning? The 'g' is the problem, even with @EVAL.
Yes, because function support will be dropped.

Or you could use variables > 1 character. Or put the % in front of the variable names.

rconn

As a matter of fact, the line in question,
Code:
``set /a n=10*n+g``
conforms to the the rules mentioned in CMD's "SET /?" and it works in CMD.
Code:
``````C:\Users\vefatica> ver

Microsoft Windows [Version 6.1.7601]

C:\Users\vefatica> set n=2

C:\Users\vefatica> set g=5

C:\Users\vefatica> set /a n=10*n+g
25``````
And it works in 21.01.50. But in order to do that, I had to remove the undocumented behavior (functions, floating point, etc.).

vefatica

And it works in 21.01.50. But in order to do that, I had to remove the undocumented behavior (functions, floating point, etc.).
Does any of this have to do with m_apm_set_string() not working very well? For example "a","b", and"c" cause a "non-digit" complaint from MAPM; "d" causes an access violation; "g" turns into the number 3, "gg" into 93.

vefatica

FWIW ...
The original version of the BTM:
Code:
``````v:\> timer number.btm
Timer 1 on: 15:55:46
381654729
Timer 1 off: 15:57:02  Elapsed: 0:01:16.63``````
A tweaked version:
Code:
``````v:\> timer number.btm
Timer 1 on: 17:09:16
381654729
Timer 1 off: 17:09:27  Elapsed: 0:00:11.59``````
The speed increase was about half due to BTM tweaks (notably, keep it short and unset as much as you can) and about half due to the math observation that the 4th and 8th digits had to be 2 or 6. Here's the tweaked version.
Code:
``````setlocal
unalias *
unset *
do a=1 to 9 by 2
do b=2 to 8 by 2
do c=1 to 9 by 2
do d=2 to 6 by 4
do f=2 to 8 by 2
do g=1 to 9 by 2
do h=2 to 6 by 4
do i=1 to 9 by 2
set /a n=100*a+10*b+c & if %@eval[n MOD 3] NE 0 iterate
set /a n=10*n+d & if %@eval[n MOD 4] NE 0 iterate
set /a n=100*n+50+f & if %@eval[n MOD 6] NE 0 iterate
set /a n=(10*n+g) & if %@eval[n MOD 7] NE 0 iterate
set /a n=10*n+h & if %@eval[n MOD 8] NE 0 iterate
set /a n=10*n+i & if %@eval[n MOD 9] NE 0 iterate
do z=1 to 9 (if %@index[%n,%z] == -1 (set x=1 & leave))
if defined x (unset x & iterate)
echo %n & quit
enddo
enddo
enddo
enddo
enddo
enddo
enddo
enddo``````

rconn

Does any of this have to do with m_apm_set_string() not working very well? For example "a","b", and"c" cause a "non-digit" complaint from MAPM; "d" causes an access violation; "g" turns into the number 3, "gg" into 93.
No, it has nothing to do with that.

vefatica

Taking further advantage of the fact that the 4th and 8th digits must (one of) 2 and 6,
Code:
``````v:\> timer number.btm
Timer 1 on: 21:45:57
381654729
Timer 1 off: 21:46:02  Elapsed: 0:00:05.47

v:\> type number.btm
setlocal
unalias *
unset *
do a=1 to 9 by 2
do b=2 to 8 by 2
do c=1 to 9 by 2
do d=2 to 6 by 4
set h=%@if[%d == 2,6,2]
do f=2 to 8 by 2
do g=1 to 9 by 2
do i=1 to 9 by 2
set /a n=100*a+10*b+c & if %@eval[n MOD 3] NE 0 iterate
set /a n=10*n+d & if %@eval[n MOD 4] NE 0 iterate
set /a n=100*n+50+f & if %@eval[n MOD 6] NE 0 iterate
set /a n=(10*n+g) & if %@eval[n MOD 7] NE 0 iterate
set /a n=10*n+h & if %@eval[n MOD 8] NE 0 iterate
set /a n=10*n+i & if %@eval[n MOD 9] NE 0 iterate
do z=1 to 9 (if %@index[%n,%z] == -1 (set x=1 & leave))
if defined x (unset x & iterate)
echo %n & quit
enddo
enddo
enddo
enddo
enddo
enddo
enddo``````