This will give you all the dates that have a unique set of digits 1900 to
9999 - probably more efficient ways to do it but this runs sub second on my
machine and spits out 44,640 values. Have not done any testing or checking
but it'll give you at least an idea.

CREATE CURSOR w_dates (uniquedate D)

FOR lnYear = 1900 TO 9999

  STORE 0 TO lnCheck
  STORE .F. TO llDuplicate
  
  *- Check the year part for duplicate number usage
  STORE STR(m.lnYear, 4) TO lcYear
  FOR n = 1 TO 4
  
    STORE VAL(SUBSTR(m.lcYear, n, 1)) TO lnVal
  
    IF BITTEST(m.lnCheck, m.lnVal)
      STORE .T. TO llDuplicate
      EXIT
    ELSE
      lnCheck = BITSET(m.lnCheck, m.lnVal)
    ENDIF 
  
  ENDFOR
  
  IF m.llDuplicate
    LOOP
  ENDIF
  
  STORE m.lnCheck TO lnCheckYr
    
  *-------------------------------------------
  *- Process Months
  *-------------------------------------------
  FOR lnMth = 1 TO 12
  
    *- Check the mth + year part for duplicate number usage
    STORE .F. TO llDuplicate
  
    STORE PADL(m.lnMth, 2, "0") TO lcMth
    FOR n = 1 TO 2
  
    STORE VAL(SUBSTR(m.lcMth, n, 1)) TO lnVal
  
      IF BITTEST(m.lnCheck, m.lnVal)
        STORE .T. TO llDuplicate
        EXIT
      ELSE
        lnCheck = BITSET(m.lnCheck, m.lnVal)
      ENDIF 
    
    ENDFOR 
    
    IF m.llDuplicate
     
      STORE m.lnCheckYr TO lnCheck  && Restore baseline to the year value
      LOOP
      
    ENDIF
    
    STORE m.lnCheck TO lnCheckYrMth
    
    *-------------------------------------------
    *- Process Days
    *-------------------------------------------
  
    *- How many days in the month ?
    lnDays = ICASE(;
      INLIST(m.lnMth, 1, 3, 5, 7, 8, 10, 12), 31, ;
      m.lnMth = 2, 28, ;
      30)
      
    *- Is this a leap Year ?
    IF m.lnMth = 2 AND MOD(m.lnYear, 4) = 0 AND IIF(MOD(m.lnYear, 100) = 0,
IIF(MOD(m.lnYear, 400) = 0, .T., .F.), .T.)
      STORE 29 TO lnDays
    ENDIF
    
    FOR lnDay = 1 to m.lnDays
    
      *- Check the mth + year + day parts for duplicate number usage
      STORE .F. TO llDuplicate
    
      STORE PADL(m.lnDay, 2, "0") TO lcDay
      FOR n = 1 TO 2
    
      STORE VAL(SUBSTR(m.lcDay, n, 1)) TO lnVal
    
        IF BITTEST(m.lnCheck, m.lnVal)
          STORE .T. TO llDuplicate
          EXIT
        ELSE
          lnCheck = BITSET(m.lnCheck, m.lnVal)
        ENDIF 
      
      ENDFOR 
      
      IF NOT m.llDuplicate
      
        INSERT INTO w_dates (;
            uniquedate) ;
          VALUES (;
            DATE(m.lnYear, m.lnMth, m.lnDay))
        
      ENDIF      
    
      STORE m.lnCheckYrMth TO lnCheck  && Restore baseline to the year +
month value - check next day in month.
        
    ENDFOR 
    
    STORE m.lnCheckYr TO lnCheck  && Check Next Mth in Year
  
  ENDFOR
  
ENDFOR  

-----Original Message-----
From: ProfoxTech [mailto:profoxtech-boun...@leafe.com] On Behalf Of Gene
Wirchenko
Sent: Monday, 18 July 2016 2:29 AM
To: profoxt...@leafe.com
Subject: Checking for All-Different Characters

Hello:

      I write a logic/math puzzle each week.  They appear in my blog
(http://genew.ca/) and two local newspapers.

      Here is the latest problem:

      "Consider a date in YYYY-MM-DD format.  What is the next date where
all eight digits will be different?"

      I solved this by hand.  I decided to verify my solution with a
program.  I often cook up something in GW-BASIC, but since VFP has date
functions, I decided to go with it.

      It was very easy to set up the framework of the loop.  What threw me
for a loop is how to check that all of the digits are different.  I ended up
converting the date to string with dtos() and then testing the string with a
rather ugly-looking condition.  Is there something faster?

***** Start of Code *****
* 16s-16.prg
* Date Puzzle
* Last Modification: 2016-07-17
*
* Consider a date in YYYY-MM-DD format.  What is the next date where all
* eight digits will be different?

    ? "*** Execution begins."
    ? program()
    close all
    clear all

    set talk off
    set exact on
    set century on
    set date ansi

    *

    local startdate
    startdate=date()

    ? "Start Date: "+transform(startdate)

    local trydate, looping
    trydate=startdate
    looping=.t.
    do while looping

       local trydtos
       trydtos=dtos(trydate)
       if right(trydtos,4)="0101"
          ? "Working on year "+left(trydtos,4)
          endif

       if;
        iif("0"$trydtos,1,0)+;
        iif("1"$trydtos,1,0)+;
        iif("2"$trydtos,1,0)+;
        iif("3"$trydtos,1,0)+;
        iif("4"$trydtos,1,0)+;
        iif("5"$trydtos,1,0)+;
        iif("6"$trydtos,1,0)+;
        iif("7"$trydtos,1,0)+;
        iif("8"$trydtos,1,0)+;
        iif("9"$trydtos,1,0)#8
          trydate=trydate+1
       else     && solution
          looping=.f.
          endif

       enddo

    ? "Solution is "+transform(trydate)+"."

    *

    close all
    clear all
    ? "*** Execution ends."
    return
***** End of Code *****

Sincerely,

Gene Wirchenko


[excessive quoting removed by server]

_______________________________________________
Post Messages to: ProFox@leafe.com
Subscription Maintenance: http://mail.leafe.com/mailman/listinfo/profox
OT-free version of this list: http://mail.leafe.com/mailman/listinfo/profoxtech
Searchable Archive: http://leafe.com/archives/search/profox
This message: 
http://leafe.com/archives/byMID/profox/00b801d1e090$a791d5c0$f6b58140$@ozemail.com.au
** All postings, unless explicitly stated otherwise, are the opinions of the 
author, and do not constitute legal or medical advice. This statement is added 
to the messages for those lawyers who are too stupid to see the obvious.

Reply via email to