From 7ebfde42fe733e489a38644eaa666c1bc1e2816b Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Thu, 16 Jul 2015 13:17:31 -0500 Subject: [PATCH] Add a perl script to generate puzzles. --- a2sudoku/generateSudoku.pl | 141 +++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100755 a2sudoku/generateSudoku.pl diff --git a/a2sudoku/generateSudoku.pl b/a2sudoku/generateSudoku.pl new file mode 100755 index 0000000..aa8e187 --- /dev/null +++ b/a2sudoku/generateSudoku.pl @@ -0,0 +1,141 @@ +#!/usr/bin/perl -w +# +# To use this generator, first you need node.js and this +# sudoku generator: +# +# https://github.com/dachev/sudoku +# +# You should be able to get it with: +# +# sudo npm install sudoku +# +# Once you have that, you can generate 300 puzzles fairly +# quickly with the following from the shell: +# +# i=1 +# while [ $i -lt 300 ] +# do +# node lib/node_modules/sudoku/bin/sudoku.js +# i=`expr $i + 1` +# done > /tmp/puzzles.txt +# +# But the output of this isn't ready for a2sudoku. To +# turn it into the right definitions for a2sudoku, you +# need to pass it through this script: +# +# generateSudoku.pl /tmp/puzzles.txt > /tmp/newpuzzles.c +# +# Then, you just need to copy those puzzles into puzzles.c +# in the source-code and you have refreshed the puzzles. +# + + +use strict; + + +my @known; +my @solution; +my @easy; +my @medium; +my @hard; + + +sub getKnown +{ + my @result; + my $i; + my $j; + my $line; + + for ($i = 0; $i < 3; $i++) { + for ($j = 0; $j < 3; $j++) { + $line = <>; + chomp $line; + $line =~ s/_/P/g; + $line =~ s/[1-9]/S/g; + push(@result, split(/ +/, $line)); + } + $line = <>; + } + + return @result; +} + + +sub getSolution +{ + my @result; + my $i; + my $j; + my $line; + + for ($i = 0; $i < 3; $i++) { + for ($j = 0; $j < 3; $j++) { + $line = <>; + chomp $line; + push(@result, split(/ +/, $line)); + } + $line = <>; + } + + return @result; +} + + +sub generatePuzzle +{ + my $i; + my $result = +" {\n" . +" {\n" . +" "; + + for ($i = 0; $i <= $#known; $i++) { + $result .= $known[$i] . "VAL(" . $solution[$i] . "),"; + + if ($i == $#known) { + $result .= "\n }\n },\n"; + } elsif (($i % 27) == 26) { + $result .= "\n\n "; + } elsif (($i % 9) == 8) { + $result .= "\n "; + } elsif (($i % 3) == 2) { + $result .= " "; + } + } + + return $result; +} + + +# Turns out I run out of memory pretty quickly. I should look at +# putting the puzzles on disk and loading them rather than building +# them in. For now, enforce a limit to make sure we don't exceed +# limits. +my $limit = 50; +while (<>) { + chomp; + if (/^PUZZLE:/) { + @known = &getKnown; + } + + if (/^SOLUTION:/) { + @solution = &getSolution; + } + + if ((/^RATING: 0/) && + ($#easy < $limit)) { + push(@easy, &generatePuzzle); + } elsif ((/^RATING: 1/) && + ($#medium < $limit)) { + push(@medium, &generatePuzzle); + } elsif ((/^RATING: /) && + ($#hard < $limit)) { + push(@hard, &generatePuzzle); + } +} + + +print "tPuzzle easyPuzzles[] = {\n" . join("", @easy) . "};\n\n\n"; +print "tPuzzle mediumPuzzles[] = {\n" . join("", @medium) . "};\n\n\n"; +print "tPuzzle hardPuzzles[] = {\n" . join("", @hard) . "};\n\n\n";