Skip to content

Instantly share code, notes, and snippets.

@Ayiko

Ayiko/GOLF.pl Secret

Last active December 18, 2015 17:09
Show Gist options
  • Save Ayiko/9ca80fba8027b38d2129 to your computer and use it in GitHub Desktop.
Save Ayiko/9ca80fba8027b38d2129 to your computer and use it in GitHub Desktop.
My solutions for https://github.com/masak/workshop Thanks to masak++ for organizing this! Other solutions at https://gist.github.com/masak/5496294
# solution for https://github.com/masak/workshop/blob/master/GOLF.md
#
# I changed the output format to show the board layouts instead of indexes,
# purely for aesthetic reasons :)
# (1 is a queen, 0 is empty board)
use v6;
BEGIN note '# Started ' ~ DateTime.new(now).Str;
END note sprintf( '# %9.3fs', (now - BEGIN now).Num);
# It uses \n as line ending, remove 1 trailing space if you use \r\n
# (there are 7 spaces at the end of the next line, they are needed)
my %s;([^8]xx*).map({[~] .pick(8).map({0 x$_~1~0 x 7-$_~'
'})}).map({next if%s{$_}++||/1[[.**15]+|[.**17]+]<?after 1>/;.say})[^72]
# = 137 characters
# It's not the fastest, but it does generate all 72 solutions (eventually)
# (tested on perl6 version 2013.05 built on parrot 5.3.0 revision 0)
use v6;
BEGIN note '# Started ' ~ DateTime.new(now).Str;
END note sprintf( '# %9.3fs', (now - BEGIN now).Num);
use Test;
my @tests =
Q:to/END_JAVA/ => Q:to/END_JAVA/,
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}
END_JAVA
\hlkeyword{class} \hlusertype{HelloWorldApp} \{
\hlkeyword{public} \hlkeyword{static} \hlkeyword{void} main(\hlusertype{String}[] args) \{
\hlusertype{System}.out.println(\hlliteral{"Hello World!"}); \hlcomment{// Display the string.}
\}
\}
END_JAVA
Q:to/END_JAVA/ => Q:to/END_JAVA/,
class MountainBike extends Bicycle {
// new fields and methods defining
// a mountain bike would go here
}
END_JAVA
\hlkeyword{class} \hlusertype{MountainBike} \hlkeyword{extends} \hlusertype{Bicycle} \{
\hlcomment{// new fields and methods defining}
\hlcomment{// a mountain bike would go here}
\}
END_JAVA
Q:to/END_JAVA/ => Q:to/END_JAVA/,
public interface List <E> {
void add(E x);
Iterator<E> iterator();
}
END_JAVA
\hlkeyword{public} \hlkeyword{interface} \hlusertype{List} <\hlusertype{E}> \{
\hlkeyword{void} add(\hlusertype{E} x);
\hlusertype{Iterator}<\hlusertype{E}> iterator();
\}
END_JAVA
;
my @keywords = <
class interface enum package
extends implements
public private protected final static void transient
>;
my @userTypes = <
String Integer Boolean Long System List Iterator
int bool long short char
HelloWorldApp MountainBike Bicycle E
>;
# for %tests.kv -> $java is copy, $result {
loop { # see rakudobug #118705
last unless @tests;
my $p = shift @tests;
my $java = $p.key;
my $result = $p.value;
$java ~~ s:g/ '{' /\\\{/; # ::; #braces
$java ~~ s:g/ '}' /\\\}/; # ::;
$java ~~ s:g'<|w> @keywords <|w>'\\hlkeyword\{$/}'; #::; #keywords
$java ~~ s:g/(\d+)/\\hlnumber\{$0}/; #:: #numbers
$java ~~ s:g/(\" [ \\\" | <-["]> ]* \")/\\hlliteral\{$0}/; #:: #"strings"
$java ~~ s:g/(\' [ \\\' | <-[']> ]* \')/\\hlliteral\{$0}/; #:: #'chars'
$java ~~ s:g/('//' \N*)/\\hlcomment\{$0}/; #:: #comments
$java ~~ s:g' <|w> (@userTypes) <|w> '\\hlusertype\{$/}'; #::; #user types
is $java, $result;
}
use v6;
## convert full program to oneliner: ###
# Program 1 -- print the third column of each line
# First one prints Nil for missing 3rd column
perl6 -e ".split(' ')[2].say for lines" 1.txt
perl6 -n -e "say .split(' ')[2]//''" 1.txt
perl6 -n -e "say .words[2]//''" 1.txt
# Program 2 -- treat each line as a number and sum all lines
perl6 -n -e "BEGIN my $s = 0;$s+=$_;END say $s" 2.txt
perl6 -n -e "state $s = 0;$s+=$_;END say $s" 2.txt
perl6 -n -e "state $s+=$_;END say $s" 2.txt
perl6 -e "say [+] lines" 2.txt
# Program 3 -- print an empty line after each line
perl6 -e "for lines {.say;say ''}" 3.txt
perl6 -p -e "$_ ~= \"\n\"" 3.txt
perl6 -n -e ".say;say" 3.txt
# Program 4 -- number the lines
perl6 -e "my $c;say qq<{++$c}. $_> for lines" 4.txt
perl6 -p -e "$_ = \"{(state $)++}. $_\"" 4.txt # (state $) stolen from other solutions
perl6 -p -e "my $c;$_ = \"{$c++}. $_\"" 4.txt
perl6 -p -e "my $c;$_ = qq<{$c++}. $_>" 4.txt
# Program 5 -- print everything between START and END
# I assume you don't want START and END in the actual output...
perl6 -e ".say if /^START/ ^ff^ /^END/ for lines" 5.txt
perl6 -n -e ".say if /^START/ ^ff^ /^END/" 5.txt
### convert oneliner to full program: ###
# well, "full" program still looks short :) perl6++
# perl -pwle 'print " "'
use v6;
say ' ' ~ $_ for lines; # indent all lines by 4 spaces
# perl -nwle 'print if 20..30'
use v6;
.say for lines[20..30];
# perl -nwle 'print if $_ eq reverse'
use v6;
.say for lines.grep: { $_ eq .flip } # print only palindromes
# perl -pwle 's/\bPERL\b/Perl/g and $n++; END { print $n }'
use v6;
my $replacements = 0;
for lines {
$replacements++ if s:g/ <|w> PERL <|w> / Perl /; #:: # hilight fix
.say;
}
say $replacements; # number of lines with 1 or more replacements
# perl -anwle 'print join " : ", @F[2..4]'
use v6;
for lines {
# only print out columns 3..5 for each line
say .words[2..4].join: ' : '
}
# solution for https://github.com/masak/workshop/blob/master/ROMAN.md
use v6;
sub to_roman(Int $i is copy where 0 < $i < 4000) {
state @nums = <
I 1 IV 4
V 5 IX 9
X 10 XL 40
L 50 XC 90
C 100 CD 400
D 500 CM 900
M 1_000
>.reverse;
my $result = 'M' x $i div 1000;
$i %= 1000;
for @nums -> $b, $r {
while $i >= $b {
$result ~= $r;
$i -= $b;
}
}
$result;
}
multi sub MAIN() {
use Test;
plan 8;
is to_roman(1), "I", "1 gets converted to I";
is to_roman(3), "III", "3 gets converted to III";
is to_roman(4), "IV", "4 gets converted to IV";
is to_roman(9), "IX", "9 gets converted to XI";
is to_roman(66), "LXVI", "66 gets converted to LXVI";
is to_roman(77), "LXXVII", "77 gets converted to LXXVII";
is to_roman(99), "XCIX", "99 gets converted to XCIX";
is to_roman(2389), "MMCCCLXXXIX", "2389 gets converted to MMCCCLXXXIX";
say '# give a number as parameter to have that converted';
}
multi sub MAIN(Int $num) {
say to_roman($num);
}
use v6;
BEGIN note '# Started ' ~ DateTime.new(now).Str;
END note sprintf( '# %9.3fs', (now - BEGIN now).Num);
use LWP::Simple;
use JSON::Tiny;
#my $rss = LWP::Simple.get('https://news.ycombinator.com/rss');
my $rss = slurp('scraping_input_short.html');
my $keys = any('title', 'link', 'comments');
my grammar RSS {
rule TOP { ^ <.ws> <header> <item> * <.footer> $ }
rule header {
'<rss version="2.0">' '<channel>'
<title=.tag> <link=.tag> <description=.tag>
}
rule footer { '</channel>' '</rss>' }
rule item { '<item>' <tag> + '</item>' }
regex tag { '<' (\w+) '>' (.+?) '</' $0 '>' <.ws>? }
}
my class RSS::Actions {
method TOP($/) { make to-json($<item>>>.ast) }
method item($/) { make %($<tag>.map(*.ast).grep(*.key eq $keys))}
method tag($/) {
make ~$0 => $1.trim.subst(
/ '&#x' (<.xdigit>**2..4) ';' /,
{ :16(~$^m[0]).chr }, :g
)
}
}
my $m = RSS.parse($rss, :actions(RSS::Actions.new)) or die 'failed match';
say $m.ast;
use v6;
BEGIN note '# Started ' ~ DateTime.new(now).Str;
END note sprintf( '# %9.3fs', (now - BEGIN now).Num);
class Shipment {
has Str $.from is rw;
has Str $.to is rw;
has Str $.cargo is rw;
has Str $.date is rw;
has Int $.days is rw;
method gist {
"Shipment from $.from to $.to carrying $.cargo. Launched at $.date, will take $.days days."
}
method Str { Q:s:to/END/; #::; # highlight fix
shipment {
from $.from;
to $.to;
cargo $.cargo;
date $.date;
days $.days;
};
END
}
method verify {
die 'Shipment requires a from entry' unless $.from;
die 'Shipment requires a to entry' unless $.to;
$.cargo //= 'N/A';
$.date //= Date.today;
$.days //= 0;
}
}
my $currshipment = Any;
my @shipments = ();
sub shipment(&block) {
die 'Cannot put a shipment inside another shipment...' if $currshipment;
$currshipment = Shipment.new();
&block();
my $s = $currshipment;
$s.verify();
$currshipment = Any;
@shipments.push($s);
return $s
}
sub from(Str $location) {
die 'Can only be used inside a shipment block' unless $currshipment;
die 'A shipment can only contain 1 from entry' if defined $currshipment.from;
$currshipment.from = $location;
}
sub to(Str $location) {
die 'Can only be used inside a shipment block' unless $currshipment;
die 'A shipment can only contain 1 to entry' if defined $currshipment.to;
$currshipment.to = $location;
}
sub cargo(Str $cargo) {
die 'Can only be used inside a shipment block' unless $currshipment;
die 'A shipment can only contain 1 cargo entry' if defined $currshipment.cargo;
$currshipment.cargo = $cargo;
}
sub date(Str $date) {
die 'Can only be used inside a shipment block' unless $currshipment;
die 'A shipment can only contain 1 date entry' if defined $currshipment.date;
$currshipment.date = $date;
}
multi sub prefix:<days>(Int $days) {
# normal <multi sub date> gets tripped up by TimeUnit days enum :s
die 'Can only be used inside a shipment block' unless $currshipment;
die 'A shipment can only contain 1 days entry' if defined $currshipment.days;
$currshipment.days = $days;
}
multi sub prefix:<days>(Str $days) {
die 'Can only be used inside a shipment block' unless $currshipment;
die 'A shipment can only contain 1 days entry' if defined $currshipment.days;
$currshipment.days = +$days;
}
shipment {
from "Hong Kong";
to "London";
cargo "sand";
date "2013-08-03";
days 10;
}
shipment {
date "2013-07-03";
from "Antwerp";
days 2;
cargo "diamonds";
to "London";
}
for @shipments { .say; .print; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment