LoginSignup
4
4

More than 5 years have passed since last update.

1時間以内に解けなければプログラマ失格となってしまう5つの問題を会社の勉強会でやってみた(perl)

Last updated at Posted at 2015-06-11

流行りの「1時間以内に解けなければプログラマ失格となってしまう5つの問題が話題に」を会社の勉強会でやりました。
勉強会ではgistに挙げるルールだったのですが、私的にはQiitaがホームグラウンドなので、こっちにも挙げておきます。

解くのは、問題4をなめていて、70分かかり、さらにバグを見つけて結局80分かかってしまいました。
先週が問題解き、今週が答え合わせだったので、ついでに1週間でCodeGolf的ワンライナーも作ってみました。

問題1

問題1
package Question1;

use strict;
use warnings;

sub for_type {
    my @args = @_;
    my $sum = 0;
    for (my $i=0;$i < @args;$i++) {
        $sum += $args[$i];
    }
    return $sum;
}

sub while_type {
    my @args = @_;
    my $sum = 0;
    while (@args) {
        $sum += shift(@args);
    }
    return $sum;
}

sub recursion_type {
    my @args = @_;
    return @args ? shift(@args) + recursion_type(@args) : 0;
}

1;
問題1のCodeGolf
perl -e'$a+=$_ for@ARGV;warn$a' 1 2 3 4
perl -e'$a+=pop while@ARGV;warn$a' 1 2 3 4
perl -e'sub a{@_?pop()+a(@_):0};warn a(@ARGV)' 1 2 3 4

問題2

問題2
package Question2;

use strict;
use warnings;

sub list_add {
    my ($l1,$l2) = @_;
    my @ret;
    my $len = @{$l1} > @{$l2} ? @{$l1} : @{$l2};
    for (my $i =0; $i < $len; $i++) {
        push(@ret,$l1->[$i]) if ($i<@{$l1});
        push(@ret,$l2->[$i]) if ($i<@{$l2});
    }
    return @ret;
}

1;
問題2のCodeGolf
perl -e'@a=map{[split(/,/,$_)]}@ARGV;@b=@{$a[0]};@c=@{$a[1]};$l=@b>@c?@b:@c;for(0..$l-1){push(@d,$b[$_])if(@b>$_);push(@d,$c[$_])if(@c>$_)}print@d' 1,2,3,4 a,b,c,d,e,f,g

問題3

bigint使ってるけどなんかうまく動かない...でもとりあえずロジックはあってるはず

問題3
package Question3;

use strict;
use warnings;
use bigint;

sub fibonacci {
    my $now = 0;
    my @ret = (0,1);
    for (my $i = 0; $i < 99; $i++) {
        push(@ret,$ret[$i]+$ret[$i+1]);
    }
    return @ret;
}

1;
問題3のCodeGolf
perl -Mbigint -e'$r[$_]=$_<2?$_:$r[$_-2]+$r[$_-1]for(0..99);warn join",",@r'

問題4

正直これが一番悩みました、他のメンバーは5の方が難しいと言ってましたが、これってもっと簡単なやり方あるんですか?
簡単にワンライナーにできるよ、と言われましたが、正直私版のこれのワンライナーは単に長い版を文字削っただけです...

問題4
package Question4;

use strict;
use warnings;

sub kanounasaidai {
    my @args = map { $_ ."" } @_;
    my @list;
    for (my $i=0;$i<@args;$i++) {
        for (my $j=0;$j<@args;$j++) {
            next if ($i == $j);
            push(@list,[$i,$j,$args[$i].$args[$j]]); 
        }
    }
    @list = sort { $b->[2] cmp $a->[2] } @list;
    return $list[0]->[2] if (@args == 2);
    my $res = $list[0];

    my $k = -1;
    return kanounasaidai($res->[2],grep {$k++; $k != $res->[0] && $k != $res->[1]} @args);
}
問題4のCodeGolf
perl -e'sub k{@z=map{$_.""}@_;my @l;for $i.$#z){for $j(0..$#z){next if($i==$j);push(@l,[$i,$j,$z[$i].$z[$j]])}}@l=sort{$b->[2]cmp$a->[2]}@l;return $l[0]->[2] if(@z==2);$r=$l[0];$k=-1;return k($r->[2],grep{$k++;$k!=$r->[0]&&$k!=$r->[1]}@z)}warn k(@ARGV)' 9 956 978 56

問題5

一番難しいとみんな言ってたけど、5分でできましたが(ただバグあったけど)...
eval禁止縛りとかしてるから難しいのかなと思ったら、普通にみんなeval使ってたし

問題5
package Question5;

use strict;
use warnings;

sub recursive {
    my $now = shift;
    my @list = @_;
    my @ret;
    if ($now == 1) {
        @ret = ('1','-1');
    } else {
        foreach my $l (@list) {
            push(@ret,$l."+$now");
            push(@ret,$l."-$now");
            push(@ret,$l."$now");
        }
    }
    return $now == 9 ? @ret : recursive($now+1,@ret);
}

sub answer {
    my @pattern = recursive(1);
    my @ans = grep {eval($_) == 100} @pattern;
    print join("\n",@ans);
}

1;
問題5のCodeGolf
perl -e 'sub r{$n=shift;my@r=$n==1?("1","-1"):map{($_."+$n",$_."-$n",$_.$n)}@_;$n==9?@r:r($n+1,@r)}@p=r(1);@a=grep{eval($_)==100}@p;warn join("\n",@a)'
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4