Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package SaltyCracker::Sudoku;
- use 5.006;
- use strict;
- use warnings;
- use autodie;
- use feature qw<say>;
- use boolean;
- use List::Util qw<any>;
- use Data::Dumper;
- use constant SUDOKU_LEN => 81;
- use constant SUDOKU_VALID_CHARACTERS => [0, 1..9];
- use constant SUDOKU_NUMBERS => [1..9];
- use SaltyCracker::EdgeBuilder qw<:ALL>;
- use parent qw<Exporter>;
- our @EXPORT = qw<>;
- our @EXPORT_OK = qw<getSudokuData>;
- our %EXPORT_TAGS = (ALL => [@EXPORT, @EXPORT_OK]);
- =head1 NAME
- SaltyCracker::Sudoku - The great new SaltyCracker::Sudoku!
- =head1 VERSION
- Version 0.01
- =cut
- our $VERSION = '0.01';
- my $sudokuString;
- my @sudokuData;
- my $edges_ref;
- my %p_to_elem = (
- 0 => 11, 1 => 12, 2 => 13,
- 3 => 14, 4 => 15, 5 => 16,
- 6 => 17, 7 => 18, 8 => 19,
- 9 => 21, 10 => 22, 11 => 23,
- 12 => 24, 13 => 25, 14 => 26,
- 15 => 27, 16 => 28, 17 => 29,
- 18 => 31, 19 => 32, 20 => 33,
- 21 => 34, 22 => 35, 23 => 36,
- 24 => 37, 25 => 38, 26 => 39,
- 27 => 41, 28 => 42, 29 => 43,
- 30 => 44, 31 => 45, 32 => 46,
- 33 => 47, 34 => 48, 35 => 49,
- 36 => 51, 37 => 52, 38 => 53,
- 39 => 54, 40 => 55, 41 => 56,
- 42 => 57, 43 => 58, 44 => 59,
- 45 => 61, 46 => 62, 47 => 63,
- 48 => 64, 49 => 65, 50 => 66,
- 51 => 67, 52 => 68, 53 => 69,
- 54 => 71, 55 => 72, 56 => 73,
- 57 => 74, 58 => 75, 59 => 76,
- 60 => 77, 61 => 78, 62 => 79,
- 63 => 81, 64 => 82, 65 => 83,
- 66 => 84, 67 => 85, 68 => 86,
- 69 => 87, 70 => 88, 71 => 89,
- 72 => 91, 73 => 92, 74 => 93,
- 75 => 94, 76 => 95, 77 => 96,
- 78 => 97, 79 => 98, 80 => 99,
- );
- my %elem_to_p = reverse %p_to_elem;
- =head1 SYNOPSIS
- Quick summary of what the module does.
- Perhaps a little code snippet.
- use SaltyCracker::Sudoku;
- my $foo = SaltyCracker::Sudoku->new();
- ...
- =head1 EXPORT
- A list of functions that can be exported. You can delete this section
- if you don't export anything, such as for a purely object-oriented module.
- =head1 SUBROUTINES/METHODS
- =head2 checkSudokuDataLength
- =cut
- sub checkSudokuDataLength {
- my $len = @sudokuData;
- say "Validating sudoku length...";
- if ($len != SUDOKU_LEN) {
- die "[Failed] - Validating sudoku length failed...\n";
- }
- say "[Passed] - Validating sudoku length";
- }
- #;
- =head2 checkSudokuData
- =cut
- sub checkSudokuData {
- my $failed = false;
- my $valid_characters = SUDOKU_VALID_CHARACTERS;
- say "Validating sudoku characters...";
- while (my ($index, $elem) = each @sudokuData) {
- sub
- {
- say "$elem at position $index is invalid\n";
- $failed = true;
- } ->() unless any {$_ == $elem} @$valid_characters;
- }
- die "Found invalid characters... Exiting\n" if $failed;
- say "[Passed] - Validating sudoku characters";
- }
- =head2 getStartNumbers
- =cut
- sub getStartNumbers {
- my ($n) = @_;
- my @numbers;
- my $valid_numbers = SUDOKU_NUMBERS;
- my @numbers_final;
- for my $elem (@$n) {
- if ($$elem) {
- push(@numbers, $elem);
- }
- }
- for my $elem (@$valid_numbers) {
- push(@numbers_final, $elem) unless any {$elem == $$_} @numbers;
- }
- \@numbers_final;
- }
- =head2 buildEdgesRef
- =cut
- sub buildEdgesRef {
- my $edges = getEdges();
- while (my ($index, $key) = each @sudokuData) {
- my @arr;
- for my $e (@{$edges->[$index]->[1]}) {
- push(@arr, \$sudokuData[$elem_to_p{$e}]);
- }
- $edges_ref->{$p_to_elem{$index}} = {
- references => \@arr,
- value => $key,
- fixed => $key == 0 ? false : true,
- startNums => getStartNumbers(\@arr)
- };
- }
- }
- =head2 solveSudokuPuzzle
- =cut
- sub solveSudokuPuzzle {
- my @keys = sort {$a <=> $b} (keys %$edges_ref);
- my $pos = 0;
- if ($edges_ref->{$p_to_elem{$pos}}->{fixed}) {
- solveSudokuPuzzleAux($pos + 1);
- }else {
- my $a_refer = $edges_ref->{$p_to_elem{$pos}}->{references};
- my $start_nums = $edges_ref->{$p_to_elem{$pos}}->{startNums};
- for my $e (@$start_nums) {
- my $old_data = $sudokuData[$pos];
- $sudokuData[$pos] = $e;
- solveSudokuPuzzleAux($pos + 1);
- $sudokuData[$pos] = $old_data;
- }
- }
- }
- =head2 solveSudokuPuzzleAux
- =cut
- sub solveSudokuPuzzleAux {
- my ($pos) = @_;
- if ($pos < SUDOKU_LEN) {
- if ($edges_ref->{$p_to_elem{$pos}}->{fixed}) {
- solveSudokuPuzzleAux($pos + 1);
- } else {
- my $a_refer = $edges_ref->{$p_to_elem{$pos}}->{references};
- my $start_nums = $edges_ref->{$p_to_elem{$pos}}->{startNums};
- for my $e (@$start_nums) {
- next if any {$e == $$_} (@$a_refer);
- my $old_data = $sudokuData[$pos];
- $sudokuData[$pos] = $e;
- solveSudokuPuzzleAux($pos + 1);
- $sudokuData[$pos] = $old_data;
- }
- }
- }else {
- say "--------------->Found a solution<----------------------";
- for (my $i = 0; $i < SUDOKU_LEN; ++$i) {
- if ($i % 27 == 0) {
- print "\n\n\n";
- }elsif ($i % 9 == 0) {
- print "\n";
- }elsif ($i % 3 == 0) {
- print " ";
- }
- print $sudokuData[$i], " ";
- }
- print "\n\n\n\n";
- }
- }
- =head2 getSudokuData
- =cut
- sub getSudokuData {
- my ($filename) = @_;
- open(my $iFile, '<:encoding(utf-8)', $filename);
- my $sudokuStr;
- {
- local $/ = undef;
- $sudokuStr = <$iFile>;
- }
- chomp($sudokuStr);
- @sudokuData = split//,$sudokuStr;
- checkSudokuDataLength();
- checkSudokuData();
- $sudokuString = $sudokuStr;
- buildEdgesRef();
- solveSudokuPuzzle();
- }
- =head2 function2
- =cut
- sub function2 {
- }
- =head1 AUTHOR
- SaltyCracker, C<< <SaltyCracker> >>
- =head1 BUGS
- Please report any bugs or feature requests to C<bug-saltycracker-sudoku at rt.cpan.org>, or through
- the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=SaltyCracker-Sudoku>. I will be notified, and then you'll
- automatically be notified of progress on your bug as I make changes.
- =head1 SUPPORT
- You can find documentation for this module with the perldoc command.
- perldoc SaltyCracker::Sudoku
- You can also look for information at:
- =over 4
- =item * RT: CPAN's request tracker (report bugs here)
- L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=SaltyCracker-Sudoku>
- =item * AnnoCPAN: Annotated CPAN documentation
- L<http://annocpan.org/dist/SaltyCracker-Sudoku>
- =item * CPAN Ratings
- L<http://cpanratings.perl.org/d/SaltyCracker-Sudoku>
- =item * Search CPAN
- L<http://search.cpan.org/dist/SaltyCracker-Sudoku/>
- =back
- =head1 ACKNOWLEDGEMENTS
- =head1 LICENSE AND COPYRIGHT
- Copyright 2020 SaltyCracker.
- This program is free software; you can redistribute it and/or modify it
- under the terms of the the Artistic License (2.0). You may obtain a
- copy of the full license at:
- L<http://www.perlfoundation.org/artistic_license_2_0>
- Any use, modification, and distribution of the Standard or Modified
- Versions is governed by this Artistic License. By using, modifying or
- distributing the Package, you accept this license. Do not use, modify,
- or distribute the Package, if you do not accept this license.
- If your Modified Version has been derived from a Modified Version made
- by someone other than you, you are nevertheless required to ensure that
- your Modified Version complies with the requirements of this license.
- This license does not grant you the right to use any trademark, service
- mark, tradename, or logo of the Copyright Holder.
- This license includes the non-exclusive, worldwide, free-of-charge
- patent license to make, have made, use, offer to sell, sell, import and
- otherwise transfer the Package with respect to any patent claims
- licensable by the Copyright Holder that are necessarily infringed by the
- Package. If you institute patent litigation (including a cross-claim or
- counterclaim) against any party alleging that the Package constitutes
- direct or contributory patent infringement, then this Artistic License
- to you shall terminate on the date that such litigation is filed.
- Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
- AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
- THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
- YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
- CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
- CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- =cut
- 1; # End of SaltyCracker::Sudoku
Add Comment
Please, Sign In to add comment