Skip to content

Instantly share code, notes, and snippets.

@AnaTofuZ
Last active June 16, 2019 11:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AnaTofuZ/6ebe054d3dd36be87cd6241bac562c42 to your computer and use it in GitHub Desktop.
Save AnaTofuZ/6ebe054d3dd36be87cd6241bac562c42 to your computer and use it in GitHub Desktop.
hatena-summer-intern-2019

はてなインターンクイズ

  • 使用言語
    • Perl1.0
  • テストコード
    • Perl5

使い方

$docker build -t anatofuz/hatena-perl-1.0 . 
$docker run --rm -it anatofuz/hatena-perl-1.0:latest

runすると標準入力の待機画面になるので、ACII文字列を入力し、エンターキーを押すとjsonが表示されます。 (なお jqをパイプでつなげると原因は定かでないですがうまくパースできません)

テスト

$mkdir t
$mv  t_schema.json t/1_schema.json 
$mv  t_01.t t/01.t
$carton install
$perl create_packages.pl 
$carton exec -- prove -Ilib
requires "Test2::V0";
requires 'JSON';
requires 'JSON::Validator';
recommends 'JSON::XS';
#!/usr/bin/env perl
use strict;
use warnings;
use File::Path qw/mkpath/;
use FindBin;
open my $perl1_fh, '<', "perl_1.pl";
my $perl1_code = do {local $/; <$perl1_fh>};
close $perl1_fh;
$perl1_code =~ s/do//g;
my $perl5_perl1_code = 'package AnaTofuZ::ROT13;'."\n\n";
while ($perl1_code =~ /(sub \w+ \{\n(?:.*\n?)+?\})/g){
my $subroutine = $1;
my @lines = split /\n/, $subroutine;
$lines[0] .= "\n shift;";
my %def_valiables = ();
for my $line (@lines){
if ($line =~ /(\$\w+)\s+=/){
my $val_name = $1;
chomp($val_name);
unless (exists($def_valiables{$val_name})){
$line =~ s/(\$\w+\s+)=/my $1=/;
$def_valiables{$val_name}++;
}
}
$line =~ s/exit/return/;
$line =~ s/=(\s+)escape_json_elem\(/=$1escape_json_elem('test_va',/;
}
$subroutine = join("\n",@lines);
$perl5_perl1_code .= "$subroutine\n\n";
}
$perl5_perl1_code .= "1;\n";
if (! -d "$FindBin::Bin/lib/anatofuz"){
mkpath "$FindBin::Bin/lib/anatofuz";
}
open my $create_lib_fh, ">", "$FindBin::Bin/lib/anatofuz/rot13.pm";
print $create_lib_fh "$perl5_perl1_code";
close $create_lib_fh;
FROM anatofuz/perl-1.0:latest
COPY ./perl_1.pl /
ENTRYPOINT ["/usr/local/bin/perl","/perl_1.pl"]
#!/usr/bin/env perl1
$input_string = do input_string_from_stdin();
do validate_string($input_string);
$converted_string = do convert_rot13($input_string);
$ans_json = '{';
$ans_json .= do create_json_elements("answer","TARGET",1);
$ans_json .= do create_json_elements("twitter","anatofuz",1);
$ans_json .= do create_json_elements("homepage",'https://www.anatofuz.net/',1);
$ans_json .= do create_json_elements("github","anatofuz");
$ans_json .= '}';
if ($ans_json =~ /TARGET/){
$escape_conv_str = do escape_json_elem($converted_string);
$ans_json =~ s/TARGET/$escape_conv_str/g;
}
print "$ans_json\n";
exit(0);
sub convert_rot13 {
$normal_string = pop(@_);
$normal_string =~ y/A-Za-z/N-ZA-Mn-za-m/;
$normal_string;
}
sub input_string_from_stdin {
$input_string = <stdin>;
chop($input_string);
$input_string;
}
sub validate_string {
$input_string = pop(@_);
if ($input_string !~ /^[!-~]+$/){
print "invalid arguments\n";
exit(1);
}
}
sub create_json_elements {
$key = shift(@_);
$value = shift(@_);
$value = do escape_json_elem($value);
$json_elem = '';
$json_elem .= '"'.$key.'":';
$json_elem .= '"'. $value .'"';
if (@_) {
$json_elem .= ",";
}
$json_elem;
}
sub escape_json_elem {
$value = shift(@_);
$value =~ s|\\|\\\\|g;
$value =~ s|/|\\/|g;
$value =~ s|"|\\"|g;
$value;
}
#!/usr/bin/env perl
use strict;
use warnings;
use Test2::V0 -target => 'AnaTofuZ::ROT13';
use JSON;
use JSON::Validator;
use AnaTofuZ::ROT13;
subtest 'convert_rot13' => sub {
is ($CLASS->convert_rot13('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
q{NOPQRSTUVWXYZABCDEFGHIJKLM},"upcase test");
is ($CLASS->convert_rot13('NOPQRSTUVWXYZABCDEFGHIJKLM'),
q{ABCDEFGHIJKLMNOPQRSTUVWXYZ}, "upcase test");
is ($CLASS->convert_rot13('abcdefghijklmnopqrstuvwxyz'),
q{nopqrstuvwxyzabcdefghijklm}, "downcase test");
is ($CLASS->convert_rot13('nopqrstuvwxyzabcdefghijklm'),
q{abcdefghijklmnopqrstuvwxyz}, "downcase test");
is ($CLASS->convert_rot13('@$#%&*/"'),
q{@$#%&*/"}, "symbolick test");
};
subtest 'validate_string' => sub {
is ($CLASS->validate_string('ABcde@$'),
q{}, "ok");
is( $CLASS->validate_string('アスキー以外'), 1, "Not intput username" );
};
subtest 'escape_json_elem' => sub {
is ($CLASS->escape_json_elem('ABC'),
q{ABC}, "normal val");
is ($CLASS->escape_json_elem('/'),
q{\/}, "slash");
is ($CLASS->escape_json_elem('\\'),
q{\\\\}, "back slash");
is ($CLASS->escape_json_elem('"'),
q{\\"}, "double quote");
};
subtest 'create_json_elements' => sub {
is($CLASS->create_json_elements("key","val"),'"key":"val"');
my $test_json_string = '{';
$test_json_string .= $CLASS->create_json_elements("answer","TARGET",1);
$test_json_string .= $CLASS->create_json_elements("twitter","anatofuz",1);
$test_json_string .= $CLASS->create_json_elements("homepage",'https://www.anatofuz.net/',1);
$test_json_string .= $CLASS->create_json_elements("github","anatofuz");
$test_json_string .= '}';
my $jv = JSON::Validator->new->schema("file://t/1_schema.json");
is($jv->validate(decode_json($test_json_string)),0);
};
done_testing();
{
"type": "object",
"required": [
"github",
"twitter",
"answer",
"homepage"
],
"properties": {
"github": {
"type": "string",
"title": "GitHubアカウント",
"examples": [
"motemen"
]
},
"twitter": {
"type": "string",
"title": "Twitterアカウント",
"examples": [
"motemen"
]
},
"answer": {
"type": "string",
"title": "問題の解答"
},
"homepage": {
"type": "string",
"title": "ホームページ",
"description": "ホームページ、ポートフォリオなどのURL",
"examples": [
"https://motemen.github.io/"
]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment