The Daily Calendar Puzzle

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

The Daily Calendar Puzzle

#1 Post by Aacini » 18 Nov 2024 20:04

The "Daily Calendar Puzzle" is a toy comprised of a board with squares marked with the Month names, Days numbers and DayOfWeek names, and 10 different pieces that covers most squares, but leaves 3 spaces in the board. The goal of the puzzle is to place the pieces in a way that the 3 spaces corresponds to the date of each day. The toy can be made of plastic; the mine is made of wood. Below is a photo of my puzzle as I received it, so I called such a date (September/24 Monday) the "initial position".


Image


After you tried to solve the puzzle for a particular date you'll be realized that the number of possible ways to place the 10 pieces in the board is huge! So perhaps you can think to solve this puzzle via a computer program...

Below is the first version of a Batch program I wrote to solve this puzzle. Before you review it I invite you to develop your own version of such a program, or, later, to modify my code in order to make it faster. The method I used in my first version is "brute force" via a recursive subroutine, so it could take a huge amount of time to solve for a particular date depending on how different are the positions of the pieces when compared vs. the pieces in the "initial position". If a solution requires the top pieces of the "initial position" to be at bottom of the board, it would take hours or even days to solve!

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem Solving the "Daily Calendar Puzzle"
rem Antonio Perez Ayala - 18/Nov/2024

rem Empty the environment
(
   for /F "delims==" %%v in ('set') do set "%%v="
   set "ComSpec=%ComSpec%"
   set "windir=%windir%"
)
for /F %%a in ('copy /Z "%~F0" NUL') do set "CR=%%a"		

rem Fill the board with zeros
for /L %%i in (1,1,8) do for /L %%j in (1,1,7) do set "board[%%i%%j]=0"

rem Reserve empty squares (=99) at the borders
for /L %%i in (1,1,2) do set "board[%%i7]=99"
for /L %%j in (1,1,4) do set "board[8%%j]=99"

rem Reserve empty squares for today's date
rem Modify next line to match current locale, if needed
for /F "tokens=1-3 delims=/." %%a in ("%date%") do set /A "dd=1%%a%%100, mm=1%%b%%100, yyyy=%%c"
set /A "a=(mm-14)/12, dow=((1461*(yyyy+4800+a))/4+(367*(mm-2-12*a))/12-(3*((yyyy+4900+a)/100))/4+dd-32074)%%7, D=dow+1"
for /F "tokens=%D%" %%d in ("Sun Mon Tue Wed Thu Fri Sat") do echo Today's date: %yyyy%/%mm%/%dd% (%%d) & echo/
set /A "month=((mm-1)/6+1)*10+(mm-1)%%6+1, day=((dd-1)/7+3)*10+(dd-1)%%7+1, dow=(dow/4+7)*10+(dow+dow/4)%%4+4"
set /A "board[%month%]=99, board[%day%]=99, board[%dow%]=99"

rem Define all ":orientations:" of the 10 different pieces (including upside-down) via "triplets":
rem (offset Y . offset X . length X); one "triplet" for each horizontal line that comprises the piece
rem "len[]" vector store the number of triplets in each piece: 1-Large L=8, 2-Small s=4, etc.
rem The number and initial positions of the pieces appears in "Daily Calendar Pieces.png" file
set "n=0"
set "pieces="
for %%p in (
   "1-Large L:0.0.4 1.0.1:0.0.1 1.0.1 2.0.1 3.0.2:0.0.1 1.-3.4:0.0.2 1.1.1 2.1.1 3.1.1:0.0.4 1.3.1:0.0.2 1.0.1 2.0.1 3.0.1:0.0.1 1.0.4:0.0.1 1.0.1 2.0.1 3.0.2"
   "2-Small s:0.0.2 1.-1.2:0.0.1 1.0.2 2.1.1:0.0.2 1.1.2:0.0.1 1.-1.2 2.-1-1"
   "3-Large S:0.0.1 1.0.3 2.2.1:0.0.2 1.0.1 2.-1.2:0.0.1 1.-2.3 2.2.1:0.0.2 1.1.1 2.1.2"
   "4-Small d:0.0.1 1.-1.2 2.-1.2:0.0.3 1.1.2:0.0.2 1.0.2 2.0.1:0.0.2 1.0.3:0.0.1 1.0.2 2.0.2:0.0.2 1.-1.3:0.0.2 1.0.2 2.1.1:0.0.3 1.0.2"
   "5-Large I:0.0.1 1.0.1 2.0.1 3.0.1:0.0.4"
   "6-Small l:0.0.1 1.0.1 2.-1.2:0.0.3 1.2.1:0.0.2 1.0.1 2.0.1:0.0.1 1.0.3:0.0.1 1.0.1 2.0.2:0.0.1 1.-2.3:0.0.2 1.1.1 2.1.1:0.0.3 1.0.1"
   "7-Small z:0.0.2 1.1.3:0.0.1 1.0.1 2.-1.2 3.-1.1:0.0.3 1.2.2:0.0.1 1.-1.2 2.-1.1 3.-1.1:0.0.2 1.-2.3:0.0.1 1.0.2 2.1.1 3.1.1:0.0.3 1.-1.2:0.0.1 1.0.1 2.0.2 3.1.1"
   "8-Large T:0.0.1 1.0.1 2.-1.3:0.0.1 1.-2.3 2.0.1:0.0.3 1.1.1 2.1.1:0.0.1 1.0.3 2.0.1"
   "9-Small u:0.0.3 1.0.1 1.2.1:0.0.2 1.0.1 2.0.2:0.0.1 0.2.1 1.0.3:0.0.2 1.1.1 2.0.2"
  "10-Large V:0.0.1 1.0.1 2.-2.3:0.0.3 1.2.1 2.2.1:0.0.3 1.0.1 2.0.1:0.0.1 1.0.1 2.0.3" ) do (
   set /A "n+=1, t=0"
   set "pieces=!pieces! !n!"
   for /F "tokens=1* delims=:" %%a in (%%p) do (
      set "triplet=%%b"
      for /F "delims=" %%t in (^"!triplet::^=^
%Don't remove this line%
!^") do (
      set /A t+=1
      set "piece[!n!,!t!]=%%t"
      )
   )
   set "len[!n!]=!t!"
)

rem Start the recursive process
set "trace=^!time:~0,-3^! "
echo %trace% Start of process...
call :putNextPiece < NUL
echo %trace% End of process...
goto :EOF


rem Recursive subroutine that put the next piece in the board
:putNextPiece
setlocal EnableDelayedExpansion

rem Search for the first free square in the board
set "freeI="
for /L %%i in (1,1,8) do for /L %%j in (1,1,7) do if not defined freeI if "!board[%%i%%j]!" == "0" set /A "freeI=%%i,freeJ=%%j"
set "trace=!trace! %freeI%,%freeJ%="
set /P "=%trace%            !CR!"

set "processed= "
:nextPiece
rem Get the next available piece
for /F "tokens=1*" %%a in ("%pieces%") do set "nextPiece=%%a" & set "rest=%%b"

rem Test if the next piece can be inserted in the board at the free square, in anyone of its len[] orientations
set /P "=%trace%%nextPiece:~-1%!CR!"
for /L %%o in (1,1,!len[%nextPiece%]!) do (   rem Orientations in a piece
   set "piece=!piece[%nextPiece%,%%o]!"
   set "allZeros=0"
   for %%t in (!piece!) do (  rem Triplets in next orientation
      for /F "tokens=1-3 delims=." %%i in ("%%t") do (  rem OfsI.OfsJ.Length in each triplet
         set /A "I=freeI+%%i, J=freeJ+%%j"
         for /L %%# in (1,1,%%k) do (  rem Horizontal line
            if defined board[!I!!J!] (
               set /A "allZeros+=board[!I!!J!], J+=1"
            ) else (
               set "allZeros=99"
            )
         )
      )
   )
   if !allZeros! equ 0 (   rem Right orientation found:

      rem Insert this piece in the board
      set "trace=!trace!%nextPiece:~-1%"
      for %%t in (!piece!) do (  rem Triplets in the correct orientation
         for /F "tokens=1-3 delims=." %%i in ("%%t") do (  rem OfsI.OfsJ.Length in triplet
            set /A "I=freeI+%%i, J=freeJ+%%j"
            for /L %%# in (1,1,%%k) do (  rem Horizontal line
               set /A "board[!I!!J!]=%nextPiece%, J+=1"
            )
         )
      )

      rem Remove the inserted piece from the set and pass to the next one, if any
      set "pieces=%rest%"
      if defined pieces (
         call :putNextPiece
      ) else (   rem All pieces were inserted
         echo/
         echo/
         echo Solution found:
         echo/
         call :ShowBoard
         echo/
         call :ShowBoard > "Daily Calendar Solution - %yyyy%-%mm%-%dd%.txt"
         exit /B 1
      )

      rem If solution was found, cancel further processing
      if errorlevel 1 exit /B 1

      rem At this point, the inserted piece/orientation gave not a solution: remove it from board
      set "trace=!trace:~0,-1!"
      for %%t in (!piece!) do (  rem Triplets in the right orientation
         for /F "tokens=1-3 delims=." %%i in ("%%t") do (  rem OfsI.OfsJ.Length in triplet
            set /A "I=freeI+%%i, J=freeJ+%%j"
            for /L %%# in (1,1,%%k) do (  rem Horizontal line
               set /A "board[!I!!J!]=0, J+=1"
            )
         )
      )

      rem And pass to the next orientation of this piece
   )
)

rem If right orientation of this piece not found, rotate rest of pieces and try again,
rem but don't repeat the same processed piece twice
if not defined rest exit /B 0
set "processed=%processed%%nextPiece% "
for /F %%r in ("%rest%") do if not "!processed: %%r =!" == "%processed%" exit /B 0
set "pieces=%rest% %nextPiece%"
goto nextPiece


:ShowBoard
for /L %%i in (1,1,8) do (
   set "line="
   for /L %%j in (1,1,7) do (
      set "cell=!board[%%i%%j]!"
      if !cell! equ 99 set "cell= "
      set "line=!line! !cell:~-1!"
   )
   echo !line!
)
exit /B
Perhaps my code requires a radical modification, or perhaps a different, analytical method, would be more efficient...

In the included .zip file there are some auxiliary files I used to develop my program. You could print and cut the *.png files in order to create your own paper-made Daily Calendar Puzzle.

Daily Calendar Images.zip
Auxiliary images of the puzzle
(996.75 KiB) Downloaded 67 times

Enjoy! :P

Antonio

T3RRY
Posts: 250
Joined: 06 May 2020 10:14

Re: The Daily Calendar Puzzle

#2 Post by T3RRY » 20 Nov 2024 02:42

Very interesting. My first thought, just as a result if how similar the pieces are to tetriminos, is to make a tetris varient that plays out games until a solution is found. I'm sure there's probably some rules that could be applied to generating piece ordering to make solving faster.

If I remember to I might give it a go at some point.

miskox
Posts: 630
Joined: 28 Jun 2010 03:46

Re: The Daily Calendar Puzzle

#3 Post by miskox » 20 Nov 2024 08:42

Thanks! Looks great!

I had to modify

Code: Select all

for /F "tokens=1-3 delims=/." %%a in ("%date%") do set /A "dd=1%%a%%100, mm=1%%b%%100, yyyy=%%c"
to

Code: Select all

for /F "tokens=2-4 delims=/. " %%a in ("%date%") do set /A "dd=1%%a%%100, mm=1%%b%%100, yyyy=%%c"
(added space as a delimiter, changed tokens from 1-3 to 2-4 because echo %date% shows:

Code: Select all

sre. 20. 11. 2024
(sre=wednesday)

Saso

Post Reply