1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

I can't figure this one out

Discussion in 'Support' started by vefatica, Sep 14, 2017.

  1. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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 [18]  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.
     
  2. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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.
     
  3. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    730
    Likes Received:
    8
    Try this;
    Code:
    set /a n=(10*n+g)
    This returned an answer of 381654729

    Joe
     
  4. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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.
     
  5. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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
     
  6. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,092
    Likes Received:
    85
    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.
     
  7. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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.
     
  8. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,092
    Likes Received:
    85
    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.
     
  9. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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
     
  10. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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"
     
  11. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,092
    Likes Received:
    85
    Yes, because function support will be dropped.

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

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,092
    Likes Received:
    85
    And it works in 21.01.50. But in order to do that, I had to remove the undocumented behavior (functions, floating point, etc.).
     
  13. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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.
     
  14. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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
     
  15. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,092
    Likes Received:
    85
    No, it has nothing to do with that.
     
  16. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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
     

Share This Page