fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <time.h>
  4. #include <stdexcept>
  5. #include <ctime>
  6. #include <chrono>
  7. #include <stdlib.h>
  8.  
  9. using namespace std;
  10.  
  11. enum Trans { up, right, down, left, upBack, leftBack, downBack, rightBack};
  12.  
  13. // Puzzle board coordinates
  14. class Coord
  15. {
  16. public:
  17. int x;
  18. int y;
  19.  
  20. Coord(int cx,int cy){x=cx;y=cy;}
  21. Coord(){x=0;y=0;}
  22. virtual ~Coord(){}
  23. void AssignFrom(const Coord& other){x=other.x;y=other.y;}
  24. Coord(const Coord& other){AssignFrom(other);}
  25. Coord& operator=(const Coord& other){AssignFrom(other);return *this;}
  26. bool operator==(const Coord& other){if((x==other.x)&&(y==other.y)) return true; else return false;}
  27. virtual ostream& put(ostream & o,char sep=' ') const {return o<< "(x=" << x << "y=" << y << ")" << sep;}
  28.  
  29. friend ostream& operator<<(ostream& o, const Coord& p){return p.put(o);}
  30. };
  31.  
  32. // Vector used for puzzle piece definition
  33. class Vect: public Coord
  34. {
  35. public:
  36.  
  37. Vect(int vx,int vy):Coord(vx,vy){}
  38. Vect():Coord(){}
  39.  
  40. inline bool isNull(){if(x==0&&y==0) return true; else return false;}
  41. };
  42.  
  43. // Puzzle piece
  44. class Piece
  45. {
  46.  
  47. protected:
  48. Vect * baseShape;
  49. Vect * currShape;
  50.  
  51. public:
  52. int shapeLength;
  53. int origin;
  54. unsigned char value;
  55. Trans* relevantTrans;
  56. int nbRelevantTrans;
  57.  
  58. Piece(Vect shape[], int shapeLen, int val, Trans relTrans[], int nbRelTrans);
  59. virtual ~Piece();
  60. void transform(Trans transformation);
  61. Vect operator[](int index);
  62. virtual ostream& put(ostream & o,char sep=' ') const ;
  63. friend ostream& operator<<(ostream& o, const Piece& p){return p.put(o);}
  64. };
  65.  
  66. Piece::Piece(Vect shape[], int shapeLen, int val, Trans relTrans[], int nbRelTrans)
  67. {
  68. int i;
  69. shapeLength = shapeLen;
  70. baseShape = new Vect[shapeLength];
  71. currShape = new Vect[shapeLength];
  72. for(i=0;i<shapeLength;i++){
  73. baseShape[i] = shape[i];
  74. currShape[i] = shape[i];
  75. }
  76. origin = 0;
  77. value = val;
  78. nbRelevantTrans = nbRelTrans;
  79. relevantTrans = new Trans[nbRelTrans];
  80. for(i=0;i<nbRelevantTrans;i++){
  81. relevantTrans[i] = relTrans[i];
  82. }
  83. }
  84.  
  85. Piece::~Piece()
  86. {
  87. if(baseShape){
  88. delete[] baseShape;
  89. baseShape = NULL;
  90. }
  91. if(currShape){
  92. delete[] currShape;
  93. currShape = NULL;
  94. }
  95. if(relevantTrans){
  96. delete[] relevantTrans;
  97. relevantTrans = NULL;
  98. }
  99. }
  100.  
  101. Vect Piece::operator[](int index)
  102. {
  103. int actualIdx = index+origin;
  104. if(index>0) actualIdx -=1;
  105. if( (actualIdx>=0) && (actualIdx<shapeLength) )
  106. return currShape[actualIdx];
  107. else
  108. return Vect();
  109. }
  110.  
  111. void Piece::transform(Trans transformation)
  112. {
  113. for(int i=0;i<shapeLength;i++){
  114. switch(transformation){
  115. case Trans::up :
  116. currShape[i] = baseShape[i];
  117. break;
  118. case Trans::right :
  119. currShape[i].x = baseShape[i].y;
  120. currShape[i].y = -baseShape[i].x;
  121. break;
  122. case Trans::down :
  123. currShape[i].x = -baseShape[i].x;
  124. currShape[i].y = -baseShape[i].y;
  125. break;
  126. case Trans::left :
  127. currShape[i].x = -baseShape[i].y;
  128. currShape[i].y = baseShape[i].x;
  129. break;
  130. case Trans::upBack :
  131. currShape[i].x = -baseShape[i].x;
  132. currShape[i].y = baseShape[i].y;
  133. break;
  134. case Trans::rightBack :
  135. currShape[i].x = baseShape[i].y;
  136. currShape[i].y = baseShape[i].x;
  137. break;
  138. case Trans::downBack :
  139. currShape[i].x = baseShape[i].x;
  140. currShape[i].y = -baseShape[i].y;
  141. break;
  142. case Trans::leftBack :
  143. currShape[i].x = -baseShape[i].y;
  144. currShape[i].y = -baseShape[i].x;
  145. break;
  146. default:
  147. cout << "Invalid transformation " << transformation << " for piece: " << to_string(value) << endl;
  148. }
  149. }
  150. }
  151.  
  152. ostream & Piece::put(ostream & o,char sep) const
  153. {
  154. return o<<"(Piece "<< to_string(value) << ")" <<sep;
  155. }
  156.  
  157. // Puzzle board sizes definition, to be customize for other types of puzzle board
  158. #define BXL 13 // X len of the puzzle board
  159. #define BYL 14 // Y len of the puzzle board
  160. #define BOX 3 // Board origin in X, to prevent pieces from spanning out of board array
  161. #define BOY 3 // Board origin in Y, to prevent pieces from spanning out of board array
  162. // BOX and BOY depends of the max dimension of the biggest piece
  163. #define BDXL 7 // X span from board origin BOX to display area border
  164. #define BDYL 8 // Y span from board origin BOY to display area boarder
  165. // The board display area correspond to real life puzzle board
  166. // the board not displayed area is a technical area required to place pieces without spanning out of the array implementing the board
  167.  
  168. // Puzzle board, only the constructor needs to be customized to change the type of puzzle board
  169. class Board
  170. {
  171.  
  172. protected:
  173. int boardArray[BYL][BXL];
  174. Coord arrayOrigin;
  175.  
  176. void AssignFrom(const Board& other);
  177. bool putPieceSquare(Board &board, int value, Coord pos);
  178.  
  179. public:
  180. Board * next;
  181.  
  182. Board(int weekday, int monthDay, int month);
  183. Board(const Board& other){AssignFrom(other);}
  184. virtual ~Board(){}
  185. Board& operator=(const Board& other){AssignFrom(other);return *this;}
  186. void nextAvailablePos(Coord * pos);
  187. Board * putPiece(Piece &piece, Coord pos);
  188. void print();
  189. virtual ostream& put(ostream & o,char sep=' ') const ;
  190. friend ostream& operator<<(ostream& o, const Board& p){return p.put(o);}
  191. };
  192.  
  193. Board::Board(int weekday, int monthDay, int month)
  194. {
  195. // weekday from 1 to 7 with 1=Monday..7=Sunday
  196. // monthDay from 1 to 31
  197. // month from 1 for January to 12 for december
  198. int x,y;
  199. next = NULL;
  200. arrayOrigin.x= BOX;
  201. arrayOrigin.y = BOY;
  202. for(x=0;x<BXL;x++){
  203. for(y=0;y<BYL;y++){
  204. boardArray[y][x] = -1;
  205. }
  206. }
  207. for(x=arrayOrigin.x;x<(arrayOrigin.x+BDXL);x++){
  208. for(y=arrayOrigin.y;y<(arrayOrigin.y+BDYL);y++){
  209. boardArray[y][x] = 0;
  210. }
  211. }
  212. boardArray[3][9] = -1;
  213. boardArray[4][9] = -1;
  214. boardArray[10][3] = -1;
  215. boardArray[10][4] = -1;
  216. boardArray[10][5] = -1;
  217. boardArray[10][6] = -1;
  218. boardArray[((month-1)/6)+3][((month-1)%6)+3] = -1;
  219. boardArray[((monthDay-1)/7)+5][((monthDay-1)%7)+3] = -1;
  220. if((weekday-1) == 6) boardArray[9][6] = -1;
  221. else boardArray[((weekday-1)/3)+9][((weekday-1)%3)+7] = -1;
  222. }
  223.  
  224. void Board::AssignFrom(const Board& other)
  225. {
  226. int x,y;
  227. next = other.next;
  228. arrayOrigin = other.arrayOrigin;
  229. for(x=0;x<BXL;x++){
  230. for(y=0;y<BYL;y++){
  231. boardArray[y][x] = other.boardArray[y][x];
  232. }
  233. }
  234. }
  235.  
  236. void Board::nextAvailablePos(Coord * pos)
  237. {
  238. int y = arrayOrigin.y;
  239. int x;
  240. bool found = false;
  241. while(y<(BDYL+arrayOrigin.y) && (found == false)){
  242. x = arrayOrigin.x;
  243. while(x<(BDXL+arrayOrigin.x) && (found == false)){
  244. if( boardArray[y][x] == 0 ){
  245. pos->y = y-arrayOrigin.y;
  246. pos->x = x-arrayOrigin.x;
  247. found = true;
  248. }
  249. x++;
  250. }
  251. y++;
  252. }
  253. }
  254.  
  255. bool Board::putPieceSquare(Board &board, int value, Coord pos)
  256. {
  257. if( board.boardArray[board.arrayOrigin.y+pos.y][board.arrayOrigin.x+pos.x] == 0) {
  258. board.boardArray[board.arrayOrigin.y+pos.y][board.arrayOrigin.x+pos.x] = value;
  259. return true;
  260. }
  261. else return false;
  262. }
  263.  
  264. Board * Board::putPiece(Piece &piece, Coord pos)
  265. {
  266. Board * newBoard = new Board(*this);
  267. bool success;
  268. Coord currPos;
  269. int index = -1;
  270. Vect currVect;
  271. currPos = pos;
  272. success = putPieceSquare(*newBoard,piece.value,currPos);
  273. if(success){
  274. currVect = piece[index];
  275. while(!currVect.isNull())
  276. {
  277. currPos.x = currPos.x-currVect.x;
  278. currPos.y= currPos.y-currVect.y;
  279. success = putPieceSquare(*newBoard,piece.value,currPos);
  280. if(!success) {
  281. delete newBoard;
  282. return NULL;
  283. }
  284. index -= 1;
  285. currVect = piece[index];
  286. }
  287. index = 1;
  288. currPos= pos;
  289. currVect = piece[index];
  290. while(!currVect.isNull())
  291. {
  292. currPos.x= currPos.x+currVect.x;
  293. currPos.y = currPos.y+currVect.y;
  294. success = putPieceSquare(*newBoard,piece.value,currPos);
  295. if(!success) {
  296. delete newBoard;
  297. return NULL;
  298. }
  299. index += 1;
  300. currVect = piece[index];
  301. }
  302. } else {
  303. delete newBoard;
  304. return NULL;
  305. }
  306. return newBoard;
  307. }
  308.  
  309. // Print board as python list
  310. void Board::print(void)
  311. {
  312. int y,x;
  313. bool firstY,firstX;
  314. cout << "[";
  315. firstY = true;
  316. for(y=arrayOrigin.y;y<(BDYL+arrayOrigin.y);y++){
  317. if(firstY==true){
  318. cout << "[";
  319. firstY=false;
  320. } else {
  321. cout << ",[";
  322. }
  323. firstX=true;
  324. for(x=arrayOrigin.x;x<(BDXL+arrayOrigin.x);x++){
  325. if(firstX==false) cout << ",";
  326. else firstX=false;
  327. cout<<to_string(boardArray[y][x]);
  328. }
  329. cout << "]";
  330. }
  331. cout << "]";
  332. }
  333.  
  334. // Print board in ASCII art
  335. ostream & Board::put(ostream & o,char sep) const
  336. {
  337. int y,x;
  338. for(y=arrayOrigin.y-1;y<(BDYL+arrayOrigin.y);y++){
  339. for(x=arrayOrigin.x;x<(BDXL+arrayOrigin.x+1);x++){
  340. if( boardArray[y][x-1] != boardArray[y][x] ){
  341. o << "|";
  342. } else {
  343. o<<" ";
  344. }
  345. if( boardArray[y+1][x] != boardArray[y][x] ){
  346. o << "_";
  347. } else {
  348. o<<" ";
  349. }
  350. }
  351. o<<endl;
  352. }
  353. return o<<sep;
  354. }
  355.  
  356. bool Solve(Board& board, Piece * pieces[], int nbPieces, Board ** sols,int * nbTries,int * nbPlPcs,bool printSol,bool isUniqueSol, bool &keepSearching)
  357. {
  358. bool isSolution = false;
  359. Coord pos;
  360. Trans* trans;
  361. Board* newBoard;
  362. Piece ** newPieces;
  363. int i,j;
  364. int newNbPieces = nbPieces - 1;
  365. if(nbPieces != 0){
  366. board.nextAvailablePos(&pos);
  367. int pIdx=0;
  368. while(pIdx<nbPieces && keepSearching){
  369. int origin=0;
  370. while(origin<=pieces[pIdx]->shapeLength && keepSearching){
  371. trans=pieces[pIdx]->relevantTrans;
  372. int tIdx=0;
  373. while(tIdx<pieces[pIdx]->nbRelevantTrans && keepSearching){
  374. pieces[pIdx]->origin=origin;
  375. pieces[pIdx]->transform(*trans);
  376. newBoard = board.putPiece(*pieces[pIdx],pos);
  377. (*nbTries)++;
  378. if(newBoard){
  379. (*nbPlPcs)++;
  380. if(newNbPieces>0){
  381. newPieces = new Piece*[newNbPieces];
  382. j=0;
  383. for(i=0;i<nbPieces;i++){
  384. if(i!=pIdx){
  385. newPieces[j] = pieces[i];
  386. j++;
  387. }
  388. }
  389. } else {
  390. newPieces = NULL;
  391. }
  392. isSolution = Solve(*newBoard,newPieces,newNbPieces,sols,nbTries,nbPlPcs,printSol,isUniqueSol,keepSearching);
  393. if(isSolution != true){
  394. delete newBoard;
  395. }
  396. if( isUniqueSol == true && isSolution == true ){
  397. keepSearching = false;
  398. }
  399. isSolution = false;
  400. delete newPieces;
  401. }
  402. tIdx++;
  403. trans++;
  404. }
  405. origin++;
  406. }
  407. pIdx++;
  408. }
  409. } else {
  410. if(*sols){
  411. board.next = *sols;
  412. }
  413. *sols = &board;
  414. isSolution = true;
  415. if(printSol==true){
  416. cout << board << endl;
  417. }
  418. }
  419. return isSolution;
  420. }
  421.  
  422. void printWeekday(int weekdayNum)
  423. {
  424. switch(weekdayNum){
  425. case 1:
  426. cout << "Monday";
  427. break;
  428. case 2:
  429. cout << "Tuesday";
  430. break;
  431. case 3:
  432. cout << "Wednesday";
  433. break;
  434. case 4:
  435. cout << "Thursday";
  436. break;
  437. case 5:
  438. cout << "Friday";
  439. break;
  440. case 6:
  441. cout << "Saturday";
  442. break;
  443. case 7:
  444. cout << "Sunday";
  445. break;
  446. default:
  447. cout << "InvalidWeekdayNum";
  448. }
  449. }
  450.  
  451. void printMonth(int monthNum)
  452. {
  453. switch(monthNum){
  454. case 1:
  455. cout << "January";
  456. break;
  457. case 2:
  458. cout << "February";
  459. break;
  460. case 3:
  461. cout << "March";
  462. break;
  463. case 4:
  464. cout << "April";
  465. break;
  466. case 5:
  467. cout << "May";
  468. break;
  469. case 6:
  470. cout << "June";
  471. break;
  472. case 7:
  473. cout << "July";
  474. break;
  475. case 8:
  476. cout << "August";
  477. break;
  478. case 9:
  479. cout << "September";
  480. break;
  481. case 10:
  482. cout << "October";
  483. break;
  484. case 11:
  485. cout << "November";
  486. break;
  487. case 12:
  488. cout << "December";
  489. break;
  490. default:
  491. cout << "InvalidMonthNumber";
  492. }
  493. }
  494.  
  495. void printError(string msg, string arg=""){
  496. cerr << msg << " " << arg << endl;
  497. }
  498.  
  499. void printHelp(string prog)
  500. {
  501. cout << "Synopsis:\n\n [weekday day month] [-h] [-u] [-i] [-s] [-t [PcsNb] [PcsNb] [PcsNb]...]\n\nDescription:\n\n Solver for Daily Calendar Puzzle with month, day of month and day of week. Return value is 0 if at least one solution has been found or -h option is used.\n\nArguments:\n\n weekday day month\n Date to solve. weekday from 1=Monday to 7=Sunday, day from 1 to 31 and month from 1 to 12.\n\n -h Print this help\n\n -u Stop looking for solutions when a first one has been found\n\n -i Make the results appear once all of them has been found in a single line of python syntax\n\n -s Make the pieces be used with their smooth side up as reference side, instead their frosted side\n\n -t Specify which pieces can be flipped (use both sides instead reference side only)\n\n PcsNb Number of a piece in range 1-10 added after '-t' to specify a pieces which shall be used both sides during solutions searching.\n\n Pieces numbers are these ones:\n\n 7 7 4 4 4\n 1 7 7 7 4 2\n 1 6 6 3 4 2 2\n 1 10 6 3 3 3 2\n 1 10 6 6 9 9 9\n 8 10 10 10 9 9\n 8 8 8 8 5 5\n 5 5 5\n\nExample\n\n To solve Friday 23rd of January\n\n " << prog << " 5 23 1\n" << endl;
  502. }
  503.  
  504.  
  505. int main(int argc, char* argv[])
  506. {
  507. auto startTime = std::chrono::high_resolution_clock::now();
  508. int wdayNum = 0;
  509. int dayNum = 0;
  510. int monthNum = 0;
  511. int fourFlatTransLen=2;
  512. int smallSTransLen=2;
  513. int smallLTransLen=4;
  514. int tTransLen=4;
  515. int uTransLen=4;
  516. int bigSTransLen=2;
  517. int smallStailTransLen=4;
  518. int bigLTransLen=4;
  519. int qTransLen=4;
  520. int lEqualTransLen=4;
  521. bool inLine = false;
  522. bool fSide=true;
  523. Board * sols = NULL;
  524. Trans allTrans[8] = {Trans::up,Trans::right,Trans::down,Trans::left,Trans::upBack,Trans::rightBack,Trans::downBack,Trans::leftBack};
  525. Trans allFaceTrans[4] = {Trans::up,Trans::right,Trans::down,Trans::left};
  526. Trans upRightTrans[4] = {Trans::up,Trans::right,Trans::upBack,Trans::rightBack};
  527. bool isArgsValid=true;
  528. bool isArgValid;
  529. bool isHelpOpt=false;
  530. bool isArgPcsFlip=false;
  531. bool isUniqueSol=false;
  532. string prog(argv[0]);
  533. for(int i=1; i<argc;i++){
  534. isArgValid=false;
  535. string arg(argv[i]);
  536. if( isArgsValid && !isArgPcsFlip && (wdayNum == 0 || dayNum == 0 || monthNum == 0 ) ){
  537. int p;
  538. bool isNum=true;
  539. try {
  540. p = stoi(arg);// convert argument to a number
  541. } catch ( std::invalid_argument& e ){
  542. isNum=false;
  543. }
  544. if( isNum && isArgsValid && !isArgValid && wdayNum == 0 ){
  545. if( p>=1 && p<=7){
  546. wdayNum = p;// week day number, monday=1, tuesday=2...
  547. isArgValid=true;
  548. } else {
  549. printError("Week day number out of [1-7] range:",arg);
  550. isArgsValid=false;
  551. }
  552. }
  553. if( isNum && isArgsValid && !isArgValid && dayNum == 0 ){
  554. if( p>= 1 && p<=31 ){
  555. dayNum = p;//day number from 1 to 31
  556. isArgValid=true;
  557. } else {
  558. printError("Month day number out of [1-31] range:",arg);
  559. isArgsValid=false;
  560. }
  561. }
  562. if( isNum && isArgsValid && !isArgValid && monthNum == 0 ){
  563. if( p>= 1 && p<=12 ){
  564. monthNum = p;// month number, january=1, february=2...
  565. isArgValid=true;
  566. } else {
  567. printError("Month number out of [1-12] range:",arg);
  568. isArgsValid=false;
  569. }
  570. }
  571. }
  572. if( !isArgValid && isArgsValid && arg.compare("-i")==0) {
  573. inLine=true;//inline python processable printing of the results
  574. isArgValid=true;
  575. }
  576. if( !isArgValid && isArgsValid && arg.compare("-s")==0){
  577. fSide=false;//front side not used, back side of pieces are the base side to use
  578. isArgValid=true;
  579. }
  580. if( !isArgValid && isArgsValid && arg.compare("-t")==0){
  581. isArgPcsFlip = true; // next arguments are pieces numbers
  582. isArgValid=true;
  583. }
  584. if( !isArgValid && isArgsValid && arg.compare("-u")==0){
  585. isUniqueSol = true;
  586. isArgValid=true;
  587. }
  588. if( !isArgValid && isArgsValid && arg.compare("-h")==0 ){
  589. isArgValid=true;
  590. isHelpOpt=true;
  591. }
  592. if( !isArgValid && isArgsValid && isArgPcsFlip ){
  593. int p;
  594. try {
  595. p = stoi(arg);// convert argument to a number to identify the piece to use on both sides
  596. } catch ( std::invalid_argument& e){
  597. printError("Invalid piece number of range [1-10]:",arg);
  598. isArgsValid=false;
  599. }
  600. if( p<1 || p>10){
  601. printError("Invalid piece number of range [1-10]:",arg);
  602. isArgsValid=false;
  603. } else {
  604. isArgValid=true;
  605. }
  606. switch(p){
  607. case 2:
  608. smallSTransLen=4;
  609. break;
  610. case 3:
  611. smallLTransLen=8;
  612. break;
  613. case 6:
  614. bigSTransLen=4;
  615. break;
  616. case 7:
  617. smallStailTransLen=8;
  618. break;
  619. case 8:
  620. bigLTransLen=8;
  621. break;
  622. case 5:
  623. qTransLen=8;
  624. break;
  625. default:
  626. break;//other pieces are the same once returned, so they are not returned to avoid creating identical solutions
  627. }
  628. }
  629. if( !isArgValid && isArgsValid ){
  630. printError("Unkown argument:",arg);
  631. isArgsValid=false;
  632. }
  633. }
  634. if( wdayNum == 0 || dayNum == 0 || monthNum == 0 ){
  635. if(wdayNum == 0 && dayNum == 0 && monthNum == 0 && isArgsValid && !isHelpOpt){
  636. // get the current time
  637. auto now = std::chrono::system_clock::now();
  638. std::time_t time = std::chrono::system_clock::to_time_t(now);
  639. // get the current day of week, day in month, and month number
  640. std::tm* timeinfo = std::localtime(&time);
  641. wdayNum = timeinfo->tm_wday == 0 ? 7 : timeinfo->tm_wday;
  642. dayNum = timeinfo->tm_mday;
  643. monthNum = timeinfo->tm_mon + 1;
  644. cout << "No date provided, solving current date." << endl;
  645. } else {
  646. if( isArgsValid && !isHelpOpt ){
  647. isArgsValid = false;
  648. printError("Missing at least one of the following numbers : weekday day month");
  649. }
  650. }
  651. }
  652. if( !isArgsValid || isHelpOpt ) {
  653. printHelp(prog);
  654. if( isHelpOpt){
  655. exit(0);
  656. } else {
  657. exit(1);
  658. }
  659. } else {
  660. if(fSide==false){
  661. // update relevant transformations lists to put back side first to use it as base side
  662. allTrans[0] = Trans::upBack;
  663. allTrans[1] = Trans::rightBack;
  664. allTrans[2] = Trans::downBack;
  665. allTrans[3] = Trans::leftBack;
  666. allTrans[4] = Trans::up;
  667. allTrans[5] = Trans::right;
  668. allTrans[6] = Trans::down;
  669. allTrans[7] = Trans::left;
  670. allFaceTrans[0] = Trans::upBack;
  671. allFaceTrans[1] = Trans::rightBack;
  672. allFaceTrans[2] = Trans::downBack;
  673. allFaceTrans[3] = Trans::leftBack;
  674. upRightTrans[0] = Trans::upBack;
  675. upRightTrans[1] = Trans::rightBack;
  676. upRightTrans[2] = Trans::up;
  677. upRightTrans[3] = Trans::right;
  678. }
  679. // Create the 10 pieces
  680. Vect FourFlatArray[3]= {Vect(0,1),Vect(0,1),Vect(0,1)};
  681. Piece FourFlat(FourFlatArray, 3, 1, upRightTrans, fourFlatTransLen);
  682. Vect SmallSArray[3]= {Vect(0,1),Vect(1,0),Vect(0,1)};;
  683. Piece SmallS(SmallSArray, 3, 2, upRightTrans, smallSTransLen);
  684. Vect SmallLArray[3] = {Vect(0,1),Vect(1,0),Vect(1,0)};
  685. Piece SmallL(SmallLArray, 3, 3, allTrans, smallLTransLen);
  686. Vect TArray[4] = {Vect(1,0),Vect(1,0),Vect(-1,1),Vect(0,1)};
  687. Piece T(TArray, 4, 4, allFaceTrans, tTransLen);
  688. Vect QArray[4] = {Vect(0,1),Vect(1,0),Vect(0,1),Vect(-1,0)};
  689. Piece Q(QArray, 4, 5, allTrans, qTransLen);
  690. Vect BigSArray[4] = {Vect(1,0),Vect(0,1),Vect(0,1),Vect(1,0)};
  691. Piece BigS(BigSArray, 4, 6, upRightTrans, bigSTransLen);
  692. Vect SmallsTailArray[4] = {Vect(1,0),Vect(0,1),Vect(1,0),Vect(1,0)};
  693. Piece SmallsTail(SmallsTailArray, 4, 7, allTrans, smallStailTransLen);
  694. Vect BigLArray[4] = {Vect(0,1),Vect(1,0),Vect(1,0),Vect(1,0)};
  695. Piece BigL(BigLArray, 4, 8, allTrans, bigLTransLen);
  696. Vect UArray[4] = {Vect(0,1),Vect(1,0),Vect(1,0),Vect(0,-1)};
  697. Piece U(UArray, 4, 9, allFaceTrans, uTransLen);
  698. Vect LequalArray[4] = {Vect(0,1),Vect(0,1),Vect(1,0),Vect(1,0)};
  699. Piece Lequal(LequalArray, 4, 10, allFaceTrans, lEqualTransLen);
  700.  
  701. // Create the board
  702. Board puzzle(wdayNum,dayNum,monthNum);
  703. // Solving
  704. int nbTries=0;
  705. int nbSols=0;
  706. int nbPlPcs=0;
  707. Board * nextSol;
  708. // Create the list of pieces to give to the solver
  709. Piece * puzzlePieces[10] = {&FourFlat,&U,&Q,&SmallsTail,&SmallL,&BigL,&SmallS,&Lequal,&BigS,&T};//this order is from the most to least frequent appearance in first case, when pieces are used on their front side, fSide=true
  710. if(inLine==false){
  711. cout << "Solutions:" << endl;
  712. }
  713. bool keepSearching = true;
  714. // Call the solving function
  715. Solve(puzzle, puzzlePieces, 10, &sols,&nbTries,&nbPlPcs,(inLine==false),isUniqueSol,keepSearching);
  716.  
  717. if(inLine==false){
  718. // Print the solution as human readable
  719. if(sols){
  720. nbSols ++;
  721. nextSol = sols->next;
  722. while(nextSol){
  723. nbSols++;
  724. nextSol = nextSol->next;
  725. }
  726. }
  727. cout << nbSols << " solutions found after " << nbTries << " tries and "<< nbPlPcs << " pieces placed for ";
  728. printWeekday(wdayNum);
  729. cout << " " << dayNum << " ";
  730. printMonth(monthNum);
  731. cout << endl;
  732. } else {
  733. // print the solution as python dict entry
  734. cout << "\"";
  735. printWeekday(wdayNum);
  736. cout << " " << dayNum;
  737. printMonth(monthNum);
  738. cout << "\": { \"nbPcsPlaced\": " << nbPlPcs << ",\"nbTries\":" << nbTries << ", \"sols\": [";
  739. if(sols){
  740. (*sols).print();
  741. nbSols ++;
  742. nextSol = sols->next;
  743. while(nextSol){
  744. cout << ",";
  745. (*nextSol).print();
  746. nbSols++;
  747. nextSol = nextSol->next;
  748. }
  749. }
  750. cout << "], \"nbSol\": " << nbSols << "}";
  751. }
  752. if(!sols){
  753. if(fSide){
  754. // turning pieces 5 is enough to get solution for all dates like wed 27 when using frosted side only, except sun 6th apr, for which another piece need to be returned
  755. cout << "Try with option: -t 5 2 " << endl;
  756. } else {
  757. // turning piece 5 is enough when using smooth side as reference to get a solution for all dates like mon 27th which have no solution smooth side only
  758. cout << "Try with option: -t 5" << endl;
  759. }
  760. }
  761. }
  762. if(inLine==false){
  763. auto endTime = std::chrono::high_resolution_clock::now();
  764. cout << "End of program reached, execution duration: " << (float)(std::chrono::duration_cast<std::chrono::milliseconds>(endTime-startTime).count())/1000 << " seconds" << endl;
  765. }
  766. if ( !sols ){
  767. exit(1);
  768. } else {
  769. exit(0);
  770. }
  771. }
  772.  
Success #stdin #stdout 0.71s 5284KB
stdin
/*  Berechnung des Hamming-Abstandes zwischen zwei 128-Bit Werten in 	*/
/*	einer Textdatei. 													*/
/*  Die Werte müssen auf einer separaten Zeile gespeichert sein			*/
/* 																		*/
/*	Erstellt: 17.5.2010													*/
/*  Autor: Thomas Scheffler												*/

#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE 32

unsigned Hamdist(unsigned x, unsigned y)
{
  unsigned dist = 0, val = x ^ y;
 
  // Count the number of set bits
  while(val)
  {
    ++dist; 
    val &= val - 1;
  }
 
  return dist;
}



int main (void)
{
	char hex;
	int i;
	int a[ARRAY_SIZE];
	int b[ARRAY_SIZE];
	int hamDist = 0;
	FILE* fp;
	
	//Arrays mit 0 initialisieren
	for (i = 0; i < ARRAY_SIZE; ++i)
	{
  		a[i] = 0;
  		b[i] = 0;
	}

	
	fp = fopen("hex.txt","r");
	if (fp == NULL) 
	{
		printf("Die Datei hex.txt wurde nicht gefunden!");
		exit(EXIT_FAILURE);
	}

	i=0;
	printf("1.Zeile einlesen.\n");

 	while((hex=fgetc(fp))!='\n' && hex != EOF)
    {
        a[i]=strtol(&hex,0,16);
		i++;
    }
	i=0;
	printf("2.Zeile einlesen.\n");

 	while((hex=fgetc(fp))!='\n' && hex != EOF)
    {
    	b[i]=strtol(&hex,0,16);
        i++;
    }
	fclose(fp);

	printf("Hamming-Abweichung pro Nibble:\n");
	for (i = 0; i < ARRAY_SIZE; ++i)
	{
		printf ("%i\t%i\t%i\n",a[i],b[i],Hamdist(a[i],b[i]));
		hamDist += Hamdist(a[i],b[i]);
	}
	printf ("\nHamming-Abweichung der Hash-Werte:%d\n",hamDist);
}

stdout
No date provided, solving current date.
Solutions:
 _ _ _ _ _ _    
| |  _ _|  _|   
| | | |_ _|_ _  
| |_|_ _ _ _| | 
|_|  _  |  _ _| 
| |_| |_|_| |_  
|   |  _ _| | | 
|_ _|_| |  _| | 
        |_|_ _| 
 
 _ _ _ _ _ _    
| |_ _  |  _|   
| |  _| | |_ _  
| | | |_|_ _| | 
|_| |_  |  _ _| 
| |_| |_|_| |_  
|   |  _ _| | | 
|_ _|_| |  _| | 
        |_|_ _| 
 
 _ _ _ _ _ _    
|_ _ _ _|  _|   
|_ _  |_ _|_ _  
|  _|_ _|_ _  | 
| |_  |  _  |_| 
| | | |_| |_|_  
|_| |_ _|   | | 
|_ _ _| |_ _| | 
        |_ _ _| 
 
 _ _ _ _ _ _    
|  _  |    _|   
|_| |_|_ _|_ _  
| |_  |  _ _| | 
| | |_| |  _ _| 
| | | |_|_| |_  
|_| |  _ _| | | 
|_ _|_| |  _| | 
        |_|_ _| 
 
 _ _ _ _ _ _    
|  _|_ _ _ _|   
| | |_   _|_ _  
|_|_  | |  _  | 
|_  |_|_|_| |_| 
| |_ _ _| | |_  
|   |  _ _| | | 
|_ _|_| |_ _| | 
        |_ _ _| 
 
 _ _ _ _ _ _    
|_ _  |    _|   
|_  |_|_ _|_ _  
| |_ _ _|  _  | 
| |_  | |_| |_| 
| | | |_  | |_  
|_| |_ _|_| | | 
|_ _ _| |_ _| | 
        |_ _ _| 
 
 _ _ _ _ _ _    
|  _|  _|  _|   
| |_ _| | |_ _  
| | |  _|_ _| | 
|_| | | |  _ _| 
| | |_| |_| |_  
| |_|_ _ _|   | 
|_ _ _| | |_ _| 
        |_ _ _| 
 
 _ _ _ _ _ _    
|_ _ _  |  _|   
|_ _  |_| |_ _  
| | |_ _|_ _| | 
| |_  | |  _ _| 
| | |_| |_| |_  
|_| |_ _| |   | 
|_ _ _| | |_ _| 
        |_ _ _| 
 
 _ _ _ _ _ _    
| |_  |    _|   
|_  | |_ _|_ _  
| |_|_ _|  _  | 
| |_ _  |_| |_| 
| | | |_ _| |_  
|_| |  _ _| | | 
|_ _|_| |_ _| | 
        |_ _ _| 
 
 _ _ _ _ _ _    
| |_  |    _|   
|_  | |_ _|_ _  
| |_|_ _|  _  | 
| |_ _  |_| |_| 
| | | |_ _| |_  
|_| |_ _ _| | | 
|_ _ _| |_ _| | 
        |_ _ _| 
 
10 solutions found after 3791618 tries and 67448 pieces placed for Sunday 21 December
End of program reached, execution duration: 0.707 seconds