From 0cb319be54788e0a76a791fc3c7cedab3e15fdf0 Mon Sep 17 00:00:00 2001 From: juliodcs Date: Sat, 14 Nov 2020 12:07:38 +0100 Subject: juliodcs-week86 --- challenge-086/juliodcs/raku/ch-2.raku | 39 ++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/challenge-086/juliodcs/raku/ch-2.raku b/challenge-086/juliodcs/raku/ch-2.raku index 24d95396bc..ef6d7e99c7 100644 --- a/challenge-086/juliodcs/raku/ch-2.raku +++ b/challenge-086/juliodcs/raku/ch-2.raku @@ -18,12 +18,12 @@ sub solve-sudoku(@sudoku) { elsif $guess == 0 && $backtrack { # not valid guess and no more guesses to test # We give up with this position (we decrement index) - @sudoku[$y][$x] = 0; + @sudoku[$y;$x] = 0; $index--; } else { # valid guess (for now), increase index - @sudoku[$y][$x] = $guess; + @sudoku[$y;$x] = $guess; $backtrack = 0; $index++; } @@ -36,14 +36,11 @@ sub solve-sudoku(@sudoku) { # so that we can speed up the process by processing first the boxes # that have less possible guesses sub get-indexes(@sudoku) { - @sudoku>>.list.flat Z ^81 + eager @sudoku>>.list.flat Z ^81 ==> map({ $^it.tail, count-guesses @sudoku, $^it.tail }) - ==> grep *.tail > 0 - ==> sort({ $^a.tail cmp $^b.tail }) + ==> grep(*.tail > 0) + ==> sort(*.tail cmp *.tail) ==> map *.head - ==> my @indexes; - - @indexes.list } # Translate index to (y, x) matrix positions @@ -56,7 +53,7 @@ sub get-position($index) { sub count-guesses(@sudoku, $index) { my ($y, $x) := get-position $index; - @sudoku[$y][$x] > 0 + @sudoku[$y;$x] > 0 ?? 0 !! elems get-guesses @sudoku, $y, $x, 0 } @@ -68,9 +65,17 @@ sub get-guesses(@sudoku, $y, $x, $last-guess) { my @square := get-square @sudoku, $y, $x; my @all-nums := (@cross-y, @cross-x, @square).flat.sort.unique.list; - (1 .. 9) - ==> grep({ 0 == elems @all-nums.grep: * == $^guess }) - ==> grep * > $last-guess + # This 2 things puzzled me: + # 1) + # `grep(-> $guess { 0 == elems @all-nums.grep: * == $guess })` + # is almost twice as fast as: + # `grep({ $_ == none @all-nums })` + # + # 2) Using `grep(* > $last-guess)` as the first grep, is VERY slow + + eager (1 .. 9) + ==> grep(-> $guess { 0 == elems @all-nums.grep: * == $guess }) + ==> grep(* > $last-guess) } # For a (y,x) pair, it returns all the boxes of its inner square @@ -78,17 +83,17 @@ sub get-square(@sudoku, $inner-y, $inner-x) { my $y := $inner-y - $inner-y % 3; my $x := $inner-x - $inner-x % 3; - @sudoku[$y+0][$x+0], @sudoku[$y+0][$x+1], @sudoku[$y+0][$x+2], - @sudoku[$y+1][$x+0], @sudoku[$y+1][$x+1], @sudoku[$y+1][$x+2], - @sudoku[$y+2][$x+0], @sudoku[$y+2][$x+1], @sudoku[$y+2][$x+2], + @sudoku[$y+0;$x+0], @sudoku[$y+0;$x+1], @sudoku[$y+0;$x+2], + @sudoku[$y+1;$x+0], @sudoku[$y+1;$x+1], @sudoku[$y+1;$x+2], + @sudoku[$y+2;$x+0], @sudoku[$y+2;$x+1], @sudoku[$y+2;$x+2] } # Makes some guess for a box. # If we are backtracking, we set a minimum value for the guess # (previous box value) sub make-guess(@sudoku, $y, $x, $backtrack) { - my $min-guess := $backtrack ?? @sudoku[$y][$x] !! 0; - my @guesses := get-guesses(@sudoku, $y, $x, $min-guess).list; + my $min-guess := $backtrack ?? @sudoku[$y;$x] !! 0; + my @guesses := get-guesses @sudoku, $y, $x, $min-guess; @guesses.elems == 0 ?? 0 !! @guesses.head } -- cgit