diff options
| author | Jan Krňávek <Jan.Krnavek@gmail.com> | 2020-11-15 09:04:35 +0100 |
|---|---|---|
| committer | Jan Krňávek <Jan.Krnavek@gmail.com> | 2020-11-15 09:04:35 +0100 |
| commit | e29dae3e932026fa0ef6c6f57dcb07fadd52856a (patch) | |
| tree | da329e425ba812ce122f3a112461780999514cf9 | |
| parent | fe386961e5846533182f55716aa7156f34c070ed (diff) | |
| parent | 4c31310c2fcdcc28b67276d0d5a90fdf820d8b48 (diff) | |
| download | perlweeklychallenge-club-e29dae3e932026fa0ef6c6f57dcb07fadd52856a.tar.gz perlweeklychallenge-club-e29dae3e932026fa0ef6c6f57dcb07fadd52856a.tar.bz2 perlweeklychallenge-club-e29dae3e932026fa0ef6c6f57dcb07fadd52856a.zip | |
Merge remote-tracking branch 'upstream/master' into challenge-week-086
28 files changed, 2715 insertions, 1777 deletions
diff --git a/challenge-086/abigail/blog1.txt b/challenge-086/abigail/blog1.txt new file mode 100644 index 0000000000..b97c4ee817 --- /dev/null +++ b/challenge-086/abigail/blog1.txt @@ -0,0 +1 @@ +https://wp.me/pcxd30-4C diff --git a/challenge-086/abigail/perl/ch-2.pl b/challenge-086/abigail/perl/ch-2.pl index 44646e9087..ecafa5924c 100644 --- a/challenge-086/abigail/perl/ch-2.pl +++ b/challenge-086/abigail/perl/ch-2.pl @@ -316,16 +316,58 @@ foreach my $x (@INDICES) { } - ################################################################################ # -# Recursively solve the sudoku. +# Two helper functions: +# nr_of_elements: Given a bitfield, return how many elements it represents. +# elements: Given a bitfield, return the elements it represents. +# +################################################################################ + +my sub nr_of_elements ($bitfield) { + sprintf ("%b", $bitfield) =~ y/1/1/; +} + +my sub elements ($bitfield) { + grep {$bitfield & (1 << ($_ - 1))} @ELEMENTS; +} + + + +################################################################################ # -# Given a set of solved and unsolved cells, pick a cell with the least -# number of possibilities left. For each possibility, try this one, and -# recurse. If any leads to a solution, return this. Else, return false, -# so we can backtrack. -# If the set of unsolved cells is empty, we have solved the complete sudoku. +# Recursively solve the sudoku, given a set of solved cells, and a +# set of unsolved cells. +# +# o If the set of unsolved cells is empty, we have solved the complete +# sudoku, and we can return the set of solved cells. +# +# o If we have an unsolved cell with no possibilities left, there is no +# solution possible, and we return 1. +# +# o If we have cells with one possibility left, then create a todo list +# of all cells with one possibility left. Then, for each cell "c" of +# the todo list: +# - for each other unsolved cell "d" which "c" can see, remove "p" +# from its set of possibilities. +# + If, afterwards, "d" has no possibility left, +# there is no solution. +# + If, afterwards, "d" has one possibility left, +# add it to the todo list. +# - add "c" to the set of solved cells, with value "p" +# - remove "c" from the set of unsolved cells, and from the todo list. +# +# o Otherwise, pick an unsolved cell "c" with the least number of possibilities +# left (this will be at least two possibilities). +# - for each of its possibilities "p": +# + for each unsolved cell "d" which "c" can see, remove "p" +# from its set of possibilites +# + add "c" to the set of solved cells, with value "p" +# + remove "c" from the set of unsolved cells. +# + recurse: +# = if there is a solution, return the solution +# = else, try the next possibility +# - if no possibility leads to a solution, there is no solution. # # For larger sudoku's, we can reach the "deep recursion" warning, so we # silence it. @@ -340,27 +382,89 @@ sub solve ($solved, $unsolved) { return $solved unless keys %$unsolved; # - # Find the (a) square which the least possibilities; this - # means finding the set with the least amount of bits set. + # Bucketize the set of unsolved cells, by the number + # of possibilities left. + # + my @buckets; + while (my ($key, $value) = each %$unsolved) { + push @{$buckets [nr_of_elements $value]} => $key; + } + + # + # No solution possible. + # + return if $buckets [0]; + + if (@{$buckets [1] || []}) { + # + # We have unsolved cells with just one possibility left. + # + my %todo = map {$_ => 1} @{$buckets [1]}; + + # + # Make copies of the solved and unsolved structures. + # + my $new_solved = {%$solved}; + my $new_unsolved = {%$unsolved}; + + while (keys %todo) { + my ($cell) = sort keys %todo; + my $mask = $$new_unsolved {$cell}; + my ($x, $y) = split $; => $cell; + + # + # For all unsolved cells which can be seen by this cell + # eliminate the value of this cell from its possibilities. + # If no possibilities are left, return undef. If one possibility + # is left, push onto @todo. + # + # In any case, move this cell from the set of unsolved cells + # to the set of solved cells. + # + foreach my $can_see (sees ($x, $y)) { + my ($x1, $y1) = @$can_see; + if ($$new_unsolved {$x1, $y1} && + $$new_unsolved {$x1, $y1} & $mask) { + $$new_unsolved {$x1, $y1} &= ~ $mask; + my $nr_of_elements = + nr_of_elements $$new_unsolved {$x1, $y1}; + return if $nr_of_elements == 0; + $todo {$x1, $y1} = 1 if $nr_of_elements == 1; + } + } + + # + # Move cell to solved structure, and remove it from %todo. + # + $$new_solved {$cell} = (elements $mask) [0]; + delete $$new_unsolved {$cell}; + delete $todo {$cell}; + } + + # + # Recurse with the new sets + # + return solve ($new_solved, $new_unsolved); + } + + # + # Now, find a cell with the least number of possibilities left. + # That will be a cell in the first non-empty bucket. # - my ($key) = map {$$_ [0]} - sort {$$a [1] <=> $$b [1]} - map {[$_, sprintf ("%b", $$unsolved {$_}) =~ y/1/1/]} - keys %$unsolved; - my ($x, $y) = split $; => $key; - my $possibilities = $$unsolved {$key}; + my ($bucket) = grep {$_} @buckets; + my $cell = $$bucket [0]; + my ($x, $y) = split $; => $cell; # - # Guess each possibility for this key. + # Guess each possibility for this cell. # - foreach my $guess (@ELEMENTS) { + foreach my $guess (elements $$unsolved {$cell}) { my $mask = 1 << ($guess - 1); - next unless $possibilities & $mask; # # Create new solved unsolved structures, as copies from the given ones. # - my $new_solved = {%$solved}; + my $new_solved = {%$solved}; my $new_unsolved = {%$unsolved}; # @@ -371,16 +475,16 @@ sub solve ($solved, $unsolved) { # # Remove the guess from the set of unsolved cells. # - delete $$new_unsolved {$key}; + delete $$new_unsolved {$cell}; # - # Delete our guess as possibility for each square + # Delete our guess as possibility for each cell # which can be seen. # foreach my $can_see (sees ($x, $y)) { - my ($x, $y) = @$can_see; - if ($$new_unsolved {$x, $y}) { - $$new_unsolved {$x, $y} &= ~ $mask; + my ($x1, $y1) = @$can_see; + if ($$new_unsolved {$x1, $y1}) { + $$new_unsolved {$x1, $y1} &= ~ $mask; } } @@ -419,7 +523,7 @@ if (my $r = solve ($solved, $unsolved)) { } } else { - say "No solution found\n"; + say "No solution found."; } diff --git a/challenge-086/hstejas/README b/challenge-086/hstejas/README new file mode 100644 index 0000000000..969c5c0569 --- /dev/null +++ b/challenge-086/hstejas/README @@ -0,0 +1 @@ +Solution by Tejas diff --git a/challenge-086/hstejas/cpp/ch-1.cpp b/challenge-086/hstejas/cpp/ch-1.cpp new file mode 100644 index 0000000000..79fa9a55bc --- /dev/null +++ b/challenge-086/hstejas/cpp/ch-1.cpp @@ -0,0 +1,43 @@ +#include <iostream> +#include <algorithm> +#include <vector> + +// g++ --std=c++17 c1.cpp && ./a.out + +void pair_diff(unsigned int reference, std::vector<int> nums) +{ + std::sort(nums.begin(), nums.end(), std::greater<int>()); + auto start = nums.begin(); + auto curr = start; + while(start != nums.end() && curr != nums.end()) + { + ++curr; + int diff = std::abs(*start - *curr); + if(diff == reference) + { + std::cout << "1 as " << *start << " - " << *curr << " = " << diff << std::endl; + return; + } + else if (diff > reference) + { + ++start; + curr = start; + } + } + std::cout << "0" << std::endl; +} + +int main() +{ + std::vector<std::pair< int, std::vector<int>>> tests { + {7, {50, 8, 12, 15, 5} }, + {6, {1, 5, 2, 9, 7} }, + {15, {10, 30, 20, 50, 40} }, + {15, {-15, -5, -30, 20, 50, 40} } + }; + + for (auto test : tests) + { + pair_diff(test.first, test.second); + } +}
\ No newline at end of file diff --git a/challenge-086/hstejas/cpp/ch-2.cpp b/challenge-086/hstejas/cpp/ch-2.cpp new file mode 100644 index 0000000000..534a5f036b --- /dev/null +++ b/challenge-086/hstejas/cpp/ch-2.cpp @@ -0,0 +1,210 @@ +#include <array> +#include <vector> +#include <set> +#include <iostream> +#include <utility> + +// https://raw.githubusercontent.com/agauniyal/rang/master/include/rang.hpp +#include "rang.hpp" + +// g++ --std=c++17 c2.cpp -O2 && ./a.out + +namespace std +{ + std::string to_string(bool in) + { + return in ? "true" : "false"; + } +} // namespace std + +class Board +{ +public: + + Board(const std::array<std::array<int, 9>, 9>& in) + :mBoard(in) { } + + void fill(int* in) + { + for(size_t row = 0; row < mBoard.size(); row++) + { + for(size_t col = 0; col < mBoard.size(); col++) + { + *(in + (mBoard.size() * row) + col) = mBoard[row][col]; + } + } + } + + void checkPrint(const std::array<std::array<int, 9>, 9>& ref) + { + for(size_t row=0; row < mBoard.size(); row++) + { + for(size_t col=0; col < mBoard.size(); col++) + { + if(mBoard[row][col] == ref[row][col]) + { + std::cout << mBoard[row][col] << " "; + } + else + { + std::cout << rang::fg::red << mBoard[row][col] << rang::fg::reset << " "; + } + } + std::cout << std::endl; + } + } + + void print() + { + for(size_t row=0; row < mBoard.size(); row++) + { + for(size_t col=0; col < mBoard.size(); col++) + { + if(mBoard[row][col] != 0) + { + std::cout << mBoard[row][col] << " "; + } + else + { + std::cout << rang::fg::red << mBoard[row][col] << rang::fg::reset << " "; + } + } + std::cout << std::endl; + } + } + + bool solve() + { + bool result = solveNext(0, 0); + std::cout << "Solved? " << std::to_string(result) << std::endl; + return result; + } + +protected: + + bool validRow(int num, size_t row) + { + return std::find(mBoard[row].begin(), mBoard[row].end(), num) == mBoard[row].end(); + } + + bool validCol(int num, size_t col) + { + // entire col + for(size_t irow = 0; irow < mBoard.size(); irow++) + { + if(mBoard[irow][col] == num) + { + return false; + } + } + return true; + } + + bool validBox(int num, size_t row, size_t col) + { + size_t oRow = 3 * (row / 3); + size_t oCol = 3 * (col / 3); + // entire box + for(size_t irow = oRow; irow < oRow+3; irow++) + { + if(std::find(mBoard[irow].begin() + oCol, mBoard[irow].begin() + oCol + 3, num) + != (mBoard[irow].begin() + oCol + 3)) + { + return false; + } + } + return true; + } + + bool isValid(int num, size_t row, size_t col) + { + return validRow(num, row) && validCol(num, col) && validBox(num, row, col); + } + + bool solveNext(size_t row, size_t col) + { + if(mBoard[row][col] == 0) + { + for(int num = 1; num <=9; num++) + { + if(isValid(num, row, col)) + { + mBoard[row][col] = num; + size_t nextCol = col == 8 ? 0 : col+1; + size_t nextRow = col == 8 ? row + 1 : row; + if(nextRow == 9 || solveNext(nextRow, nextCol)) + { + return true; + } + mBoard[row][col] = 0; + } + } + } + else + { + size_t nextCol = col == 8 ? 0 : col + 1; + size_t nextRow = col == 8 ? row + 1 : row; + if(nextRow == 9 || solveNext(nextRow, nextCol)) + { + return true; + } + } + return false; + } + + std::array<std::array<int, 9>, 9> mBoard; +}; + +#ifdef BUILD_SHARED +extern "C" { + bool solve(int *data) + { + std::array< std::array<int, 9>, 9> input; + for(size_t row = 0; row < input.size(); row++) + { + for(size_t col = 0; col < input.size(); col++) + { + input[row][col] = *(data + (row * input.size()) + col); + } + } + + Board board(input); + board.print(); + bool ret = board.solve(); + board.print(); + board.fill(data); + return ret; + } +} +#else +int main() +{ + std::array< std::array<int, 9>, 9> solved {{ + { 4, 3, 5, 2, 6, 9, 7, 8, 1 }, + { 6, 8, 2, 5, 7, 1, 4, 9, 3 }, + { 1, 9, 7, 8, 3, 4, 5, 6, 2 }, + { 8, 2, 6, 1, 9, 5, 3, 4, 7 }, + { 3, 7, 4, 6, 8, 2, 9, 1, 5 }, + { 9, 5, 1, 7, 4, 3, 6, 2, 8 }, + { 5, 1, 9, 3, 2, 6, 8, 7, 4 }, + { 2, 4, 8, 9, 5, 7, 1, 3, 6 }, + { 7, 6, 3, 4, 1, 8, 2, 5, 9 }, + }}; + + std::array< std::array<int, 9>, 9> input {{ + { 0, 0, 0, 2, 6, 0, 7, 0, 1 }, + { 6, 8, 0, 0, 7, 0, 0, 9, 0 }, + { 1, 9, 0, 0, 0, 4, 5, 0, 0 }, + { 8, 2, 0, 1, 0, 0, 0, 4, 0 }, + { 0, 0, 4, 6, 0, 2, 9, 0, 0 }, + { 0, 5, 0, 0, 0, 3, 0, 2, 8 }, + { 0, 0, 9, 3, 0, 0, 0, 7, 4 }, + { 0, 4, 0, 0, 5, 0, 0, 3, 6 }, + { 7, 0, 3, 0, 1, 8, 0, 0, 0 }, + }}; + + Board board(input); + board.solve(); + board.print(); +} +#endif // BUILD_SHARED
\ No newline at end of file diff --git a/challenge-086/hstejas/perl/ch-1.pl b/challenge-086/hstejas/perl/ch-1.pl new file mode 100755 index 0000000000..8c1e81a7ba --- /dev/null +++ b/challenge-086/hstejas/perl/ch-1.pl @@ -0,0 +1,38 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use v5.30; + +sub pair_diff { + my $ref = abs(shift); + my @nums = sort { $b <=> $a } @{ shift @_ }; + + while(@nums) { + my $num = shift @nums; + foreach(@nums) { + my $diff = abs($num - $_); + if($diff == $ref) { + say "1 as $num - $_ = $ref"; + return; + } + elsif($diff > $ref) { + last; + } + } + } + say '0'; +} + +my $tests = { + 'Test1' => { 'ref' => 7, 'arr' => [10, 8, 12, 15, 5] }, + 'Test2' => { 'ref' => 6, 'arr' => [1, 5, 2, 9, 7] }, + 'Test3' => { 'ref' => 15, 'arr' => [10, 30, 20, 50, 40] }, + 'Test4' => { 'ref' => 15, 'arr' => [-15, -5, -30, 20, 50, 40] }, + 'Test5' => { 'ref' => -15, 'arr' => [-15, -5, -30, 20, 50, 40] }, + 'Test6' => { 'ref' => 1, 'arr' => [9, map { $_ * 10 } 1..900000 ] }, +}; + +foreach(sort keys %{$tests}) { + my $test = $tests->{$_}; + pair_diff($test->{'ref'}, $test->{'arr'}); +}
\ No newline at end of file diff --git a/challenge-086/hstejas/perl/ch-2.pl b/challenge-086/hstejas/perl/ch-2.pl new file mode 100755 index 0000000000..a72ffa21ea --- /dev/null +++ b/challenge-086/hstejas/perl/ch-2.pl @@ -0,0 +1,105 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use v5.30; + +# g++ --std=c++17 -DBUILD_SHARED ../cpp/c2.cpp -O2 -fPIC -shared -o sudoku.so +use FFI::Platypus; + +# sudo apt install libgtk3-perl +use Gtk3 -init; + +use Data::Dumper; + + +my $ffi = FFI::Platypus->new( api => 1 ); +$ffi->lib('./sudoku.so'); + +$ffi->attach( 'solve' => ['int[]'] => 'bool' ); + +my @puzzle = ( '', '', '', 2, 6, '', 7, '', 1, + 6, 8, '', '', 7, '', '', 9, '', + 1, 9, '', '', '', 4, 5, '', '', + 8, 2, '', 1, '', '', '', 4, '', + '', '', 4, 6, '', 2, 9, '', '', + '', 5, '', '', '', 3, '', 2, 8, + '', '', 9, 3, '', '', '', 7, 4, + '', 4, '', '', 5, '', '', 3, 6, + 7, '', 3, '', 1, 8, '', '', '',); + +my $window = Gtk3::Window->new ('toplevel'); +$window->signal_connect (delete_event => sub { Gtk3->main_quit }); +$window->set_title("Sudoku Solver"); +$window->set_border_width(5); + +my $provider = Gtk3::CssProvider->new(); +my $screen = Gtk3::Gdk::Screen::get_default; +Gtk3::StyleContext::add_provider_for_screen($screen, $provider, 600); +$provider->load_from_data('#boxsep { margin: 5px;} #boardsep { margin: 8px; }'); + +my @input_boxes; + +my $vbox = Gtk3::Box->new( 'vertical', 5 ); +$window->add($vbox); + +for my $row (0..8) { + if($row == 3 or $row == 6) { + my $sep = Gtk3::HSeparator->new; + $sep->set_name('boxsep'); + $vbox->add($sep); + } + + my $hbox = Gtk3::Box->new( 'horizontal', 5 ); + $vbox->add($hbox); + + for my $col (0..8) { + if($col == 3 or $col == 6) { + my $sep = Gtk3::VSeparator->new(); + $sep->set_name('boxsep'); + $hbox->add($sep); + } + my $cell = new Gtk3::Entry->new; + $cell->set_width_chars(2); + $cell->set_text($puzzle[$row*9 + $col]); + push @input_boxes, $cell; + $hbox->add($cell) + } +} +my $board_sep = Gtk3::HSeparator->new; +$board_sep->set_name('boardsep'); +$vbox->add($board_sep); + +my $solve_btn = Gtk3::Button->new('Solve'); +$solve_btn->signal_connect (clicked => sub { + my @input_nums; + foreach(@input_boxes) { + my $text = $_->get_text(); + push @input_nums, ($text ? $text : 0); + } + my $result = solve(\@input_nums); + if($result) { + for(my $i = 0; $i <= $#input_nums; $i++) { + $input_boxes[$i]->set_text($input_nums[$i]); + } + } + else { + my $error_dialog = Gtk3::MessageDialog->new($window, 'destroy-with-parent', 'error', 'ok', 'Error solving Sudoku'); + $error_dialog->present(); + $error_dialog->signal_connect( response => sub { $error_dialog->destroy() } ); + } + }); + +my $clear_btn = Gtk3::Button->new('Clear'); +$clear_btn->signal_connect (clicked => sub { + for(@input_boxes) { + $_->set_text(''); + } + }); + +my $buttons = Gtk3::HBox->new; +$buttons->add($solve_btn); +$buttons->add($clear_btn); +$vbox->add($buttons); + +$window->show_all; +Gtk3::main; diff --git a/challenge-086/lubos-kolouch/perl/ch-1.pl b/challenge-086/lubos-kolouch/perl/ch-1.pl new file mode 100644 index 0000000000..0603c9b929 --- /dev/null +++ b/challenge-086/lubos-kolouch/perl/ch-1.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl +#=============================================================================== +# +# FILE: ch-1.pl +# +# USAGE: ./ch-1.pl +# +# DESCRIPTION: Perl Weekly Challenge 086 +# Task 1 +# Pair Difference +# +# AUTHOR: Lubos Kolouch +# CREATED: 11/14/2020 01:27:06 PM +#=============================================================================== + +use strict; +use warnings; +use Data::Dumper; + +sub is_pair_difference { + my $data = shift; + + # to avoid sorting and/or scanning through all pairs in the array + # or double nested loop, + # I will convert the array to a hash, then check if the + # corresponding key exists + + my $arr = $$data{n}; + my %h; + for (@$arr) { + $h{$_} = 1; + } + + for my $x (keys %h) { + return 1 if $h{$x + $$data{a}}; + } + + return 0; +} + +use Test::More; + +is(is_pair_difference( { 'n' => [10, 8, 12, 15, 5], 'a' => 7 }), 1); +is(is_pair_difference( { 'n' => [1, 5, 2, 9, 7], 'a' => 6 }), 1); +is(is_pair_difference( { 'n' => [10, 30, 20, 50, 40], 'a' => 15 }), 0); + +done_testing; + diff --git a/challenge-086/lubos-kolouch/python/ch-1.py b/challenge-086/lubos-kolouch/python/ch-1.py new file mode 100644 index 0000000000..0f284bf4c6 --- /dev/null +++ b/challenge-086/lubos-kolouch/python/ch-1.py @@ -0,0 +1,39 @@ +#!env python +""" +#=============================================================================== +# +# FILE: ch-1.py +# +# USAGE: ./ch-1.py +# +# DESCRIPTION: Perl Weekly Challenge 086 +# Task 1 +# Pair Difference +# +# AUTHOR: Lubos Kolouch +# CREATED: 11/14/2020 01:27:06 PM +#=============================================================================== +""" + + +def is_pair_difference(n: list, a: int): + """ + # to avoid sorting and/or scanning through all pairs in the array + # or double nested loop, + # I will convert the array to a hash, then check if the + # corresponding key exists + """ + + hash_keys = {} + for number in n: + hash_keys[number] = 1 + + for x in hash_keys: + if hash_keys.get(x+a, 0): + return 1 + return 0 + + +assert is_pair_difference(n=[10, 8, 12, 15, 5], a=7) == 1 +assert is_pair_difference(n=[1, 5, 2, 9, 7], a=6) == 1 +assert is_pair_difference(n=[10, 30, 20, 50, 40], a=15) == 0 diff --git a/challenge-086/tyler-wardhaugh/clojure/src/tw/weekly/c86/t1.clj b/challenge-086/tyler-wardhaugh/clojure/src/tw/weekly/c86/t1.clj index 4a6a873bc7..762e938629 100644 --- a/challenge-086/tyler-wardhaugh/clojure/src/tw/weekly/c86/t1.clj +++ b/challenge-086/tyler-wardhaugh/clojure/src/tw/weekly/c86/t1.clj @@ -8,12 +8,11 @@ (defn pair-difference "Find a pair of coll such that their difference equals the target" [target coll] - (let [freqs (frequencies coll) - s (-> freqs keys set) - repeater (fn [v] (when v (repeat 2 v)))] - (if (zero? target) - (->> freqs (filter (fn [[_ v]] (> v 1))) ffirst repeater) - (->> s (keep (fn [v] (let [k (+ target v)] (when (s k) [v k])))) first)))) + (let [xf (if (zero? target) + (keep (fn [[k v]] (when (> v 1) k))) + (map key)) + s (into #{} xf (frequencies coll))] + (->> s (filter #(s (+ target %))) first))) (defn -main "Run Task 1 with a target A and a list of numbers N, defaulting to the diff --git a/challenge-086/tyler-wardhaugh/lua/README.md b/challenge-086/tyler-wardhaugh/lua/README.md index 5a776b300d..ad70c646d1 100644 --- a/challenge-086/tyler-wardhaugh/lua/README.md +++ b/challenge-086/tyler-wardhaugh/lua/README.md @@ -21,3 +21,4 @@ Run the project's tests (all the samples from the task descriptions plus some ot * [Lua](https://www.lua.org/) 5.3 * [LuaRocks](https://luarocks.org/) * [busted](https://olivinelabs.com/busted/) (a unit testing framework) +* [Moses](https://yonaba.github.io/Moses/) (a Lua utility-belt library) diff --git a/challenge-086/tyler-wardhaugh/lua/ch-1.lua b/challenge-086/tyler-wardhaugh/lua/ch-1.lua new file mode 100755 index 0000000000..8e9eda4572 --- /dev/null +++ b/challenge-086/tyler-wardhaugh/lua/ch-1.lua @@ -0,0 +1,28 @@ +#!/usr/bin/env lua + +local t1 = {} + +function t1.pair_difference(target, coll) + local freq = {} + for _, v in ipairs(coll) do freq[v] = (freq[v] or 0) + 1 end + + for k, v in pairs(freq) do + if (freq[k + target]) and ((target ~= 0) or (v > 1)) then + return 1 + end + end + + return 0 +end + +function t1.run(args) + local target = tonumber(args[1]) + table.remove(args, 1) + + local coll = {} + for _, v in ipairs(args) do table.insert(coll, tonumber(v)) end + + print(t1.pair_difference(target, coll)) +end + +return t1 diff --git a/challenge-086/tyler-wardhaugh/lua/ch-2.lua b/challenge-086/tyler-wardhaugh/lua/ch-2.lua new file mode 100755 index 0000000000..2b3a453fdb --- /dev/null +++ b/challenge-086/tyler-wardhaugh/lua/ch-2.lua @@ -0,0 +1,250 @@ +#!/usr/bin/env lua + +--[[ + This is a Lua implementation of Peter Novig's excellent sudoku solver, + originally written in Python: + [Solving Every Sudoku Puzzle](http://norvig.com/sudoku.html) +--]] + +local M = require('moses') + +local t2 = {} + + +--[[ utility ]]-- +function t2.contains(tbl, elem) + for _, v in pairs(tbl) do + if v == elem then return true end + end + return false +end + +function t2.slurp(input) + local fh = assert(io.open(input, "r")) + local text = fh:read("*all") + fh:close() + return text +end + +function t2.deep_copy(tbl) + local copy = {} + for k, v in pairs(tbl) do + copy[k] = v + end + return copy +end + +function t2.dict(tbl) + local result = {} |
