Skip to content
Browse files

initial commit

  • Loading branch information...
0 parents commit 7b0054655e29fd0d2b488730310695960cdb57d7 @masak committed Dec 10, 2012
Showing with 651 additions and 0 deletions.
  1. +15 −0 README.md
  2. +5 −0 notes.md
  3. +106 −0 rules.md
  4. +43 −0 t1/base-test
  5. +45 −0 t1/description.md
  6. +49 −0 t2/base-test
  7. +27 −0 t2/description.md
  8. +79 −0 t3/base-test
  9. +93 −0 t3/description.md
  10. +62 −0 t4/base-test
  11. +31 −0 t4/description.md
  12. +60 −0 t5/base-test
  13. +36 −0 t5/description.md
15 README.md
@@ -0,0 +1,15 @@
+## The tasks
+
+t1. Tell knights from knaves based on what they say.
+
+t2. Generate rectangle haikus.
+
+t3. Arrange wire crossings to rearrange wires.
+
+t4. Simulate rain in a world of cubes.
+
+t5. Distribute weights in bags evenly.
+
+## See also
+
+`rules.md` and `notes.md`
5 notes.md
@@ -0,0 +1,5 @@
+## Things that might be good to know
+
+We'd rather not go changing the `description` and `base-test` files
+after having released them, but sometimes new information turns up.
+This is where we'll put it.
106 rules.md
@@ -0,0 +1,106 @@
+## How to win
+
+* A randomly chosen person wins...
+
+* ...unless people actually send in solutions.
+
+* Then the choice is made from the "winning set" of people who submitted
+ solutions to the most exercises. (Put differently, if you've submitted
+ solutions to strictly fewer exercises than someone else, you're not in the
+ winning set.)
+
+* If there's a single contestant in the winning set, that contestant wins.
+
+* Otherwise, the choice of winner is made by us (masak & moritz) based as
+ much as possible on code quality.
+
+Since "code quality" is a slightly subjective measure, let us provide a few
+hints of what we'll be looking for:
+
+* Correctness.
+* Readability.
+* Consistency.
+* Clarity of intent.
+* Algorithmic efficiency.
+* Idiomatic use of Perl 6.
+* Brevity.
+
+In short, what we're looking for is top-quality code. That's how you win.
+
+You're free to make use of your own judgment in the shaping of your
+code. If you use code that doesn't originate with you, please indicate
+so in your comments. There's a spectrum of "copying" here: implementing
+an algorithm from somewhere is perfectly fine; sending in a copy of
+someone else's solution isn't.
+
+One final thing. Please be aware that, by entering the contest, you're not
+guaranteed the prize. That is, we're not legally bound to hand out the prize
+to you for any reasons *you* can think of. We might decide to hand out the
+prize to everybody, nobody, or the *worst* coder. We won't, though. We'll
+hand out the prize to the best coder. So just be best, and you'll be fine.
+Make sure you read each problem description carefully.
+
+## How to write a solution
+
+You're free to code however you want, but for the purposes of easy comparison
+between submissions, we have a few requests.
+
+* Put your main Perl 6 script in a file called `code` in the respective
+ task directory.
+
+* Make sure this code passes all the tests in `t1/base-test`,
+ `t2/base-test`, etc.
+
+We've created the `base-test` files to ascertain a couple of basic
+requirements about input and output. This is just to have some common basis
+of comparison between the submissions.
+
+You're certainly allowed to write and include your own tests in a t/ directory,
+and to separate code into modules in a `lib/` directory, as long as the file
+`t1/code`, etc., remains the main script. The `base-test` script will set
+`PERL6LIB` so that modules in the `lib/` directory are found.
+
+With everything else -- choice of algorithm, indentation, comments, naming --
+you're completely free -- encouraged, even -- to use your own good judgment.
+
+When you're ready to submit a solution, send the file(s) along to
+cmasak@gmail.com. Put them in a `.zip` file if you want. You're free to send in
+solutions individually or all at once. Don't wait until the last moment with
+sending in solutions.
+
+If you're one of those Git octocats, you might want to consider cloning this
+repository, and then just building an archive out of your latest version:
+
+ $ git archive -o p6cc-solutions-by-jrandomhacker.zip HEAD
+
+Both Rakudo and Niecza are appropriate platforms for developing solutions for
+the contest, and we're flexible as to under which version/release you've
+written your code.
+
+See the [compiler feature matrix](http://perl6.org/compilers/features) or ask
+on `#perl6` for up-to-date info about compiler features.
+
+We appreciate if you tell us which compiler version you're using, but in
+a pinch we'll figure it out. `:-)` The `base-test` files respond to an
+environment flag `PERL6EXECUTABLE` that you can set if your Perl 6 executable
+is not named `perl6`. For Niecza, something like `mono run/Niecza.exe` ought to
+work.
+
+You're allowed to send in several solutions to the same problem, but only the
+last one will count, and please don't send more than a total of 10. :-) All
+solutions will be published after the conclusion of the contest. All are up for
+review.
+
+## How to have the appropriate amount of fun
+
+First off, if you haven't entered the contest yet — do so! You've nothing
+to lose.
+
+Secondly, Perl 6 is a shoestring project but with very dedicated people who
+are working toward a single vision. (Or, on the days when we have a head-ache,
+double vision.) Part of this whole enterprise is making sure we're learning,
+about programming, about languages, and about communities. In some loose sense,
+that's what this contest is about too: learning new things, and enjoying the
+experience.
+
+So, enjoy!
43 t1/base-test
@@ -0,0 +1,43 @@
+#! /usr/bin/env perl
+use strict;
+use warnings;
+
+use Test::More tests => 8;
+
+my $code_file = 'code';
+$ENV{PERL6LIB} = 'lib';
+my $perl6 = $ENV{PERL6EXECUTABLE} || 'perl6';
+
+sub run {
+ my ($input) = @_;
+
+ open my $INPUT, '>', 'input';
+ print {$INPUT} $input;
+ close $INPUT;
+
+ my $output = `$perl6 $code_file < input 2>&1`;
+ unlink 'input';
+
+ return $output;
+}
+
+die qq[NO FILE "$code_file"]
+ unless -e $code_file;
+
+die qq[\nFILE "$code_file" DOES NOT COMPILE]
+ if system("$perl6 -c $code_file > /dev/null");
+
+is run(""), "";
+is run("marmelade"), "Lines must be on the form '<name>: <utterance>'\n";
+is run("A: The quick brown fox."),
+ "Unrecognized utterance 'The quick brown fox.'\n";
+
+is run("A: A is a knight."), "Many solutions:\nA: knight\nA: knave\n";
+is run("A: A is a knave."), "No solutions.\n";
+
+is run("A: B is a knight."), "A mentions B but B doesn't say anything.\n";
+is run("A: A and C are of the same type."),
+ "A mentions C but C doesn't say anything.\n";
+
+is run("A: A and B are of the same type.\nB: A and B are of different types.\n"),
+ "A: knave; B: knight\n";
45 t1/description.md
@@ -0,0 +1,45 @@
+## Tell knights from knaves based on what they say
+
+On the mythical island of Smul, people suffer from a rare genetic disorder that
+make them either tell the truth all the time, or lie all the time. These are
+the only two types of people on the island, known as knights and knaves,
+respectively.
+
+Write a program that takes as input a number of utterances by islanders, and
+outputs for each person whether that person is a knight or a knave. If there is
+no possible assignment that works, the program should report that no solution
+exists. In the case of multiple solutions, the program should report every
+possible solution.
+
+The islanders can make four different classes of utterances:
+
+ X is a knight.
+ X is a knave.
+ X and Y are of the same type.
+ X and Y are of different types.
+
+(Here, X and Y are used as metavariables, of course, and can in fact be any
+name of an islander.)
+
+Islanders can refer to each other. The same islander can make several
+utterances. If an islander mentions another islander that doesn't say anything,
+your program should consider the entire input to be erroneous.
+
+Here are a few examples:
+
+ A: A is a knight.
+
+Both a knight and a knave would assert the same thing. So this input has two
+solutions.
+
+ B: B is a knave.
+
+Neither a knight or a knave would ever say this about themselves. So this input
+allows no solution.
+
+ C: C and D are of the same type.
+ D: D and C are of different types.
+
+Here, the two islanders are contradicting each other, so one of them must be a
+knight and the other a knave. But this is exactly what D is saying, so D is the
+knight. One solution.
49 t2/base-test
@@ -0,0 +1,49 @@
+#! /usr/bin/env perl
+use strict;
+use warnings;
+
+use Test::More tests => 5;
+
+my $code_file = 'code';
+$ENV{PERL6LIB} = 'lib';
+my $perl6 = $ENV{PERL6EXECUTABLE} || 'perl6';
+
+sub run {
+ my $output = `$perl6 $code_file 2>&1`;
+
+ return $output;
+}
+
+sub conforms {
+ my ($output) = @_;
+
+ # A haiku has three lines
+ my @lines = split /\n/, $output;
+ return unless @lines == 3;
+
+ # All lines should be of the same length
+ return unless length($lines[0]) == length($lines[1])
+ && length($lines[0]) == length($lines[2]);
+
+ # No double spaces
+ return if $output =~ / /;
+
+ # No punctuation
+ $output =~ s/[[:alpha:]]//g;
+ $output =~ s/ //g;
+ $output =~ s/\n//g;
+ return if $output;
+
+ return 1;
+}
+
+die qq[NO FILE "$code_file"]
+ unless -e $code_file;
+
+die qq[\nFILE "$code_file" DOES NOT COMPILE]
+ if system("$perl6 -c $code_file > /dev/null");
+
+# Let's just test it five times
+for (1..5) {
+ ok conforms(run);
+}
27 t2/description.md
@@ -0,0 +1,27 @@
+## Generate rectangle haikus
+
+Write a program that generates haikus. A haiku has three lines, where the first
+and last lines have five syllables each, and the middle line has seven. For the
+purpose of this exercise, each line consists only of letters and spaces.
+
+The haikus generated have the additional requirement that each line be of equal
+length. The length requirement should not be gamed in any way, for example by
+padding lines with spaces.
+
+ since this one does it
+ rectangle plus a haiku
+ it serves as fine text
+
+The program should attempt to generate a new haiku each time. The haiku should
+consist of English words. If the words make sense in some kind of sentence
+structure, that's considered a big bonus. Humor and/or deeper meanings are even
+bonuser.
+
+If you attempt to cheat at this task, you will be defeated by people who don't.
+
+You're free to supply your own wordlist. How you count syllables is up to you,
+and part of the task. You won't be challenged on trivial differences in
+syllable counts.
+
+It's OK for the program to run for a while, but it should preferably terminate
+within a reasonable span of time.
79 t3/base-test
@@ -0,0 +1,79 @@
+#! /usr/bin/env perl
+use strict;
+use warnings;
+
+use Test::More tests => 2;
+
+my $code_file = 'code';
+$ENV{PERL6LIB} = 'lib';
+my $perl6 = $ENV{PERL6EXECUTABLE} || 'perl6';
+
+sub run {
+ my ($param) = @_;
+
+ my $output = `$perl6 $code_file $param 2>&1`;
+ return $output;
+}
+
+sub trim_trailing_space {
+ my ($line) = @_;
+ $line =~ s/ +$//;
+ return $line;
+}
+
+sub trim_trailing_spaces {
+ my ($text) = @_;
+ return join "",
+ map { trim_trailing_space($_) . "\n" }
+ split "\n", $text;
+}
+
+die qq[NO FILE "$code_file"]
+ unless -e $code_file;
+
+die qq[\nFILE "$code_file" DOES NOT COMPILE]
+ if system("$perl6 -c $code_file > /dev/null");
+
+is trim_trailing_spaces(run("0123456789")), <<'OUTPUT';
+0 __ 0
+
+1 __ 1
+
+2 __ 2
+
+3 __ 3
+
+4 __ 4
+
+5 __ 5
+
+6 __ 6
+
+7 __ 7
+
+8 __ 8
+
+9 __ 9
+OUTPUT
+
+is trim_trailing_spaces(run("0123456798")), <<'OUTPUT';
+0 ____ 0
+
+1 ____ 1
+
+2 ____ 2
+
+3 ____ 3
+
+4 ____ 4
+
+5 ____ 5
+
+6 ____ 6
+
+7 ____ 7
+
+8 _ _ 9
+ \/
+9 _/\_ 8
+OUTPUT
93 t3/description.md
@@ -0,0 +1,93 @@
+## Arrange wire crossings to rearrange wires
+
+Ten wires are come in from the left. Ten wires leave to the right. Write a
+program that, given a permutation of the digits 0..9, arranges crossings on a
+grid that places the wires in the order designated by the permutation.
+
+The output consists of a grid whose elements connect the left and right sides.
+Each cell of the grid is either *empty* (in that it just lets the wires
+through), or a *crossing* (in that it lets the wires trade places). Two
+crossings can never be placed vertically adjacent to each other. (This is
+equivalent to saying that the wires never split or merge, they only permute.)
+
+Often, solutions require crossings to be spread out not just vertically but
+also horizontally. It is considered elegant not to make the grid wider than it
+has to be.
+
+Examples:
+
+ Input: 1032547698
+
+ Output:
+
+ 0 _ _ 1
+ \/
+ 1 _/\_ 0
+
+ 2 _ _ 3
+ \/
+ 3 _/\_ 2
+
+ 4 _ _ 5
+ \/
+ 5 _/\_ 4
+
+ 6 _ _ 7
+ \/
+ 7 _/\_ 6
+
+ 8 _ _ 9
+ \/
+ 9 _/\_ 8
+
+(This permutation is simply flipping wires pairwise.)
+
+ Input: 1234567890
+
+ Output:
+
+ 0 _ _________________ 1
+ \/
+ 1 _/\ _______________ 2
+ \/
+ 2 ___/\ _____________ 3
+ \/
+ 3 _____/\ ___________ 4
+ \/
+ 4 _______/\ _________ 5
+ \/
+ 5 _________/\ _______ 6
+ \/
+ 6 ___________/\ _____ 7
+ \/
+ 7 _____________/\ ___ 8
+ \/
+ 8 _______________/\ _ 9
+ \/
+ 9 _________________/\_ 0
+
+(The simplest way to bubble 0 to the bottom.)
+
+ Input: 5012367894
+
+ 0 _________ _ 5
+ \/
+ 1 _______ /\_ 0
+ \/
+ 2 _____ /\___ 1
+ \/
+ 3 ___ /\_____ 2
+ \/
+ 4 _ /\_______ 3
+ \/
+ 5 _/\ _______ 6
+ \/
+ 6 ___/\ _____ 7
+ \/
+ 7 _____/\ ___ 8
+ \/
+ 8 _______/\ _ 9
+ \/
+ 9 _________/\_ 4
+
+(The simplest way to bubble 4 and 5 simultaneously.)
62 t4/base-test
@@ -0,0 +1,62 @@
+#! /usr/bin/env perl
+use strict;
+use warnings;
+
+use Test::More tests => 5;
+
+my $code_file = 'code';
+$ENV{PERL6LIB} = 'lib';
+my $perl6 = $ENV{PERL6EXECUTABLE} || 'perl6';
+
+sub run {
+ my ($input) = @_;
+
+ open my $INPUT, '>', 'input';
+ print {$INPUT} $input;
+ close $INPUT;
+
+ my $output = `$perl6 $code_file < input 2>&1`;
+ unlink 'input';
+
+ return $output;
+}
+
+die qq[NO FILE "$code_file"]
+ unless -e $code_file;
+
+die qq[\nFILE "$code_file" DOES NOT COMPILE]
+ if system("$perl6 -c $code_file > /dev/null");
+
+is run(""), "0\n";
+is run("bzzt\n"), qq[Unrecognized line: "bzzt"\n];
+
+is run(<<'INPUT'), "1\n";
+(0, -1, 0)
+(0, 0, -1)
+(-1, 0, 0)
+(0, 0, 1)
+(1, 0, 0)
+INPUT
+
+is run(<<'INPUT'), "2\n";
+(0, -2, 0)
+(0, -1, -1)
+(-1, -1, 0)
+(0, -1, 1)
+(1, -1, 0)
+(0, 0, -1)
+(-1, 0, 0)
+(0, 0, 1)
+(1, 0, 0)
+INPUT
+
+is run(<<'INPUT'), "1\n";
+(0, -2, 0)
+(0, -1, -1)
+(-1, -1, 0)
+(0, -1, 1)
+(1, -1, 0)
+(0, 0, -1)
+(0, 0, 1)
+(1, 0, 0)
+INPUT
31 t4/description.md
@@ -0,0 +1,31 @@
+## Simulate rain in a world of cubes
+
+Write a program that calculates the volume of rain water collected in the cube
+world described below.
+
+The cube world &mdash; given as input &mdash; consists of a finite set of cubes
+on integer coordinates `(x, y, z)`. The positive `y` coordinate means "up".
+
+An infinite amount of rain then falls from an infinite height. Both of these
+infinities are taken to really mean "large enough as to make no difference".
+As it lands on cubes, the water will follow predictable rules:
+
+* Rain falls everywhere.
+
+* Water falling will land on the first cube below it. It does not fall through
+ cubes.
+
+* Water will collect on levels where walls on all sides will keep it in.
+
+* Water will produce vertical waterfalls where such walls are missing.
+
+* Cubes are packed tightly enough that gaps between cubes sharing an edge will
+ not let water through. However, the same gaps will readily let air through if
+ water needs to displace air for some reason.
+
+Waterfalls work in the simplest way imaginable: if water "escapes" from a
+structure of cubes, it will fall straight down along the first available
+"chute" of cube-formed empty cells until it hits a cube. (Which it may not
+necessarily do. A waterfall may go on to infinite depth.) As a waterfall hits a
+cube, it behaves just like other kinds of water: it may spread, collect, and
+form new waterfalls as needed.
60 t5/base-test
@@ -0,0 +1,60 @@
+#! /usr/bin/env perl
+use strict;
+use warnings;
+
+use Test::More tests => 7;
+
+my $code_file = 'code';
+$ENV{PERL6LIB} = 'lib';
+my $perl6 = $ENV{PERL6EXECUTABLE} || 'perl6';
+
+sub run {
+ my ($input) = @_;
+
+ open my $INPUT, '>', 'input';
+ print {$INPUT} $input;
+ close $INPUT;
+
+ my $output = `$perl6 $code_file < input 2>&1`;
+ unlink 'input';
+
+ return $output;
+}
+
+die qq[NO FILE "$code_file"]
+ unless -e $code_file;
+
+die qq[\nFILE "$code_file" DOES NOT COMPILE]
+ if system("$perl6 -c $code_file > /dev/null");
+
+is run(""), "Please supply a positive integer on the first line\n";
+is run("foo"), "Please supply a positive integer on the first line\n";
+is run("1\n2\n3"), "Too many lines of input -- expected two lines\n";
+
+is run(<<'INPUT'), <<'OUTPUT';
+5
+
+INPUT
+() () () () ()
+OUTPUT
+
+is run(<<'INPUT'), <<'OUTPUT';
+3
+1.0 1.0 1.0
+INPUT
+(1.0) (1.0) (1.0)
+OUTPUT
+
+is run(<<'INPUT'), <<'OUTPUT';
+2
+1.0 2.0 3.0 4.0
+INPUT
+(1.0 4.0) (2.0 3.0)
+OUTPUT
+
+is run(<<'INPUT'), <<'OUTPUT';
+3
+1 2
+INPUT
+(1) (2) ()
+OUTPUT
36 t5/description.md
@@ -0,0 +1,36 @@
+## Distribute weights in bags evenly
+
+Write a program that takes a positive integer N as input, followed by zero or
+more positive numbers representing weights. The output should be those same
+weights, but distributed into N bags.
+
+The distribution should be such that all the bags weigh about the same. Or, put
+differently, you'll want to minimize on some measure (of your own choosing)
+that goes to zero when the bags weigh the same.
+
+There's a weak expectation that your program not take a very long time to run,
+even as the number of bags and weights grows. In fact, it's more important for
+the program to scale well on N and the number of weights than for it to get the
+optimal distribution all of the time.
+
+Example input may look like this:
+
+ 3
+ 1.0 2.0 3.0 4.0 5.0
+
+In this case, there's a perfectly balanced distribution:
+
+ (1.0 4.0) (2.0 3.0) (5.0)
+
+You are expected to provide canonical output, where within each bag the weights
+are listed in their original order, and the bags are listed according to the
+original order of their first weight. (And empty bags at the end.)
+
+Here's an other example:
+
+ 3
+ 1 2
+
+Here, we can obviously not balance things out, so we do the best we can:
+
+ (1) (2) ()

0 comments on commit 7b00546

Please sign in to comment.
Something went wrong with that request. Please try again.