turugina

next >>

クリップボードへの転送 (Nested Flatten)
vimでは、*レジスタに対する操作がクリップボードに対する操作になります。

ノーマルコマンドでは、
"*yw (1単語ヤンク(コピー))
"*p (現在位置の後ろにペースト)
等になります。
1
2
3
4
5
" クリップボードに hoge を突っ込む
:call setreg("*", "hoge")

" クリップボードから取り出す
:let b:var = getreg("*");
疑似並行処理 (Nested Flatten)
みんな普通に並行処理書いてるような気がするけど、
お題の「擬似」はどこに行ったんだろうと
思わなくもなく。

というわけで、Perl/Tkで擬似並行処理
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
use strict;
use warnings;

use Tk;

my $lblvar='';
my $num = 1;
my $al = 'A';

# ウィンドウとラベル
# ラベルに文字が追加されていく
my $mw = Tk::MainWindow->new;
$mw->Label(-textvariable => \$lblvar)->pack(qw/-fill both/);

# Windowが表示されたらタイマ開始
$mw->bind(q/<Expose>/ => sub {
    $mw->after(timergen() , \&append_number);
    $mw->after(timergen() , \&append_alphabet);
});

$mw->MainLoop;

sub timergen
{ int rand 3000 };

sub append
{ $lblvar .= ($lblvar ? ',' : '') . shift; }

sub append_number
{
  return if $num > 10;

  append($num++);
  $mw->after(timergen() , \&append_number);
}

sub append_alphabet
{
  return if $al gt 'J';

  append($al++);
  $mw->after(timergen() , \&append_alphabet);
}
世界時計 (Nested Flatten)
DateTime と関連モジュールを使って。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
use strict;
use warnings;

use DateTime;
use DateTime::TimeZone;
use DateTime::Format::Japanese qw/:constants/;

my $dt = DateTime->now;

my $fmt = DateTime::Format::Japanese->new(
  year_format => FORMAT_GREGORIAN,
  number_format => FORMAT_ROMAN,
  output_encoding => q/sjis/,
);


print_time("現在の時刻", "local", $dt, $fmt);
print_time("グリニッジ標準時", "GMT", $dt, $fmt);
print_time("アメリカ・ロサンゼルスの時刻", "America/Los_Angeles", $dt, $fmt);

sub print_time
{
  my ($desc, $tzname, $dt, $fmt) = @_;

  $dt->set_time_zone( DateTime::TimeZone->new(name => $tzname) );
  print "$desc は @{[$fmt->format_datetime($dt)]} です。\n";
}
漢数字で九九の表 (Nested Flatten)
見直してみたら
「みんな」じゃなかった(現時点で英単語識別子を使ってるのはCとJavaだけ)
ごめんなさい m(_ _)m
英語はみんなやってるのでローマ数字で
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Module Doukaku
    Enum Roman As Integer
        NONE
        I
        II
        III
        IV
        V
        VI
        VII
        VIII
        IX
        X
    End Enum
    Dim Japanize As String() = {"〇", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"}
    Sub Main()
        For row As Roman = Roman.I To Roman.IX
            For col As Roman = Roman.I To Roman.IX
                Dim ans As Integer = row * col

                If ans < Roman.X Then
                    Console.Write("  ")
                    Console.Write(Japanize(ans))
                Else
                    Console.Write(Japanize(ans / Roman.X))
                    Console.Write(Japanize(ans Mod Roman.X))
                End If
                Console.Write(" ")
            Next
            Console.WriteLine("")
        Next
        Console.ReadLine()
    End Sub
End Module
π (Nested Flatten)
今更ながらfactorialのつもりのサブルーチン名がfractになってることに気が付いた。
恥さらしもいいとこだ orz...
ビジュアル的にはこっちのほうがおもしろい
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
use strict;
use warnings;

use bignum;

use Memoize;

sub fract
{
  my $n = shift;
  $n == 0 || $n == 1 ? 1 :
  $n * fract($n-1);
}
sub f
{
  my $n = shift;
  $n < 0 ? 0 :
  fract(2 * $n) /
  ((2 ** (4 * $n + 1)) * (fract($n) ** 2) * (2 * $n + 1)) +
  f($n-1);
}
memoize(q/fract/);
memoize(q/f/);

my $N = 1024;

print "@{[6 * f($_)]}\n" for 1 .. $N;
とりあえず、参考ページにあった数式で素直に計算。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
use strict;
use warnings;

use bignum;

use List::Util qw/reduce/;
use Memoize;

sub fract
{
  $_[0] == 0 || $_[0] == 1 ? 1 :
  $_[0] * fract($_[0]-1);
}
memoize(q/fract/);

my $N = 32;

print 6 * reduce {
  no warnings qw/once/;
  $a + $b
} map {
  fract(2 * $_) /
  ((2 ** (4 * $_ + 1)) * (fract($_) ** 2) * (2 * $_ + 1))
} 0 .. $N;
タブ区切りデータの処理 (Nested Flatten)

「第4カラムの値にそれぞれ1を加える」が抜けてますよー

何とか。
しかし何か美しくない...
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

namespace
{

class Row
{
  std::vector<std::string> data_;

  friend std::istream& operator>>(std::istream&, Row&);
  friend std::ostream& operator<<(std::ostream&, const Row&);

  public:
  std::size_t find(const std::string& key) const; 

  std::string& operator[](std::size_t i)
  { return data_.at(i); }
  const std::string& operator[](std::size_t i) const
  { return data_.at(i); }

  bool empty() const
  { return data_.empty() || data_.size() == 1 && data_[0] == ""; }
};

std::istream&
operator>>(std::istream& is, Row& r_)
{
  Row r;
  std::string line;
  std::getline(is, line);
  
  std::string::size_type i, o = 0; 
  while ((i = line.find("\t", o)) != std::string::npos)
  {
    r.data_.push_back(line.substr(o, i - o));
    o = i+1;
  }
  r.data_.push_back(line.substr(o));
  std::swap(r, r_);
  return is;
}

std::ostream&
operator<<(std::ostream& os, const Row& r)
{
  std::copy(r.data_.begin(), r.data_.end(), std::ostream_iterator<std::string>(os, "\t"));
  os << "\n";
  return os;
}

std::size_t
Row::find(const std::string& key)
const
{
  std::vector<std::string>::const_iterator it =
    std::find(data_.begin(), data_.end(), key);
  if ( it == data_.end() )
    throw "not found";
  return std::distance(data_.begin(), it);
}

typedef Row Header;
class Table
{
  Header header_;
  std::vector<Row> rows_;

  friend std::istream& operator>>(std::istream&, Table&);
  friend std::ostream& operator<<(std::ostream&, const Table&);

  public:
    void sort_by(std::size_t idx);
    void swap_columns(std::size_t col1, std::size_t col2);
    template <typename Filter>
      void filter(std::size_t idx, Filter f);

  private:
    class comparator
      : public std::binary_function<bool, Row, Row>
    {
      std::size_t col_;
      public:
      comparator(std::size_t col) : col_(col) {}

      bool operator()(const Row& r1, const Row& r2) const
      { return r1[col_] < r2[col_]; }
    };
};

std::istream&
operator>>(std::istream& is, Table& t)
{
  is >> t.header_;

  std::istream_iterator<Row> b(is),e;
  std::copy(b, e, std::back_inserter(t.rows_));
  if (t.rows_.back().empty())
    t.rows_.erase(t.rows_.end() - 1);

  return is;
}

std::ostream&
operator<<(std::ostream& os, const Table& t)
{
  os << t.header_;
  std::copy(t.rows_.begin(), t.rows_.end(), std::ostream_iterator<Row>(os, ""));
  return os;
}

void 
Table::sort_by(std::size_t idx)
{
  comparator comp(idx);
  std::sort(rows_.begin(), rows_.end(), comp);
}

void
Table::swap_columns(std::size_t col1, std::size_t col2)
{
  if ( col1 == col2 ) return;
  std::swap(header_[col1], header_[col2]);
  std::vector<Row>::iterator it = rows_.begin();
  for ( ; it != rows_.end(); ++it )
    std::swap((*it)[col1], (*it)[col2]);
}

template <typename Filter>
void
Table::filter(std::size_t idx, Filter f)
{
  std::vector<Row>::iterator it = rows_.begin();
  for ( ; it != rows_.end(); ++it )
  {
    std::stringstream ss((*it)[idx]);
    typename Filter::result_type v;
    ss >> v;
    v = f(v);
    ss.clear();
    ss << v;
    (*it)[idx] = ss.str();
  }
}

int filter(int i)
{ return i+1; }

} // namespace

int main()
{
  std::istringstream ss(
      "ID\tSurname\tForename\tAge\n"
      "1\tSato\tHanako\t17\n"
      "0\tSuzuki\tTaro\t18\n"
      );

  Table t;
  ss >> t;
  std::cout << t << "\n=====\n";

  t.sort_by(0);
  t.swap_columns(1,2);
  t.filter(3, std::ptr_fun(filter));

  std::cout << t << "\n";
  return 0;
}
数値リストの圧縮 (Nested Flatten)

#7713 をperlに移植した感じになりました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
use strict;
use warnings;

my @list = (1, 3, 4, 5, 6, 12, 13, 15, 20, 25, 26, 27);

my $prevd = $list[0];
my @result = ([+$list[0]]);
for (my $idx = 1; $idx < @list; ++$idx) {
    my $d = $list[$idx] - $list[$idx - 1];

    if ( $prevd && $prevd != $d ) {
        push @result, [$list[$idx]];
        $prevd = 0;
    }
    else {
        push @{$result[$#result]}, $list[$idx];
        $prevd = $d;
    }
}

@result =
map {
    if ( @$_ > 2 ) {
        my $d = $_->[1] - $_->[0];
        [@$_[0, $#$_], ($d>1)?($d):()];
    }
    else {
        @$_;
    }
} @result;

use Data::Dumper;
print Dumper(\@result);
2^i * 3^j * 5^k なる整数 (Nested Flatten)
素因数分解していくバージョンで
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
:new
:let s:n=1
:let s:m=0
:while s:m < 100
: if s:n != 1 && s:n % 2 != 0 && s:n % 3 != 0 && s:n % 5 != 0
:   let s:n = s:n + 1
:   continue
: endif
: let s:_ = s:n
: let s:i = 0
: let s:j = 0
: let s:k = 0
: while s:_ % 2 == 0
:   let s:_ = s:_ / 2
:   let s:i = s:i + 1
: endwhile
: while s:_ % 3 == 0
:   let s:_ = s:_ / 3
:   let s:j = s:j + 1
: endwhile
: while s:_ % 5 == 0
:   let s:_ = s:_ / 5
:   let s:k = s:k + 1
: endwhile
: if s:_ == 1
:   call append(s:m, printf("%d = 2^%d * 3^%d * 5^%d", s:n, s:i, s:j, s:k))
:   let s:m = s:m + 1
: endif
: let s:n = s:n + 1
:endwhile
:unlet! s:n
:unlet! s:m
:unlet! s:i
:unlet! s:j
:unlet! s:k
:unlet! s:_
しまった、これでは12の次が15(3*5)じゃなくて14(2*7)になってしまう。
反省して--self。
そして、まともに動くものを。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <map>

std::map<int,int> factor(int n)
{
  std::map<int, int> r;
  r[2] = r[3] = r[5] = 0;
  while ( n%2==0 ) { n/=2; ++r[2]; }
  while ( n%3==0 ) { n/=3; ++r[3]; }
  while ( n%5==0 ) { n/=5; ++r[5]; }

  if ( n != 1 ) r.clear();
  return r;
}

int main()
{
  for ( int i = 1, n = 0; n < 100; ++i ) {
    std::map<int,int> f = factor(i);

    if ( !f.empty() ) {
      std::cout << i << " = 2^" << f[2] <<
                        " * 3^" << f[3] <<
                        " * 5^" << f[5] << "\n";
      ++n;
    }
  }
  return 0;
}
i,j,k は示さなくてもいいそうなので、簡単に。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <iostream>

int main()
{
  int n = 0;
  for ( int i = 1; n < 100; ++i )
    if ( i == 1 || i % 2 == 0 || i % 3 == 0 || i % 5 == 0 ) {
      std::cout << i << ", ";
      ++n;
    }
  std::cout << "\n";
  return 0;
}
one-linerというかgolfというか...
アルゴリズムは他の皆さんと同じです。
1
2
3
1==shift@z&&++$n&&printf"%d = 2^%d * 3^%d *%s 5^%d\n",@z
while$n<100&&(@z=(++$i,$i,0,0,'',0))&&
map{$z[0]/=$_,++$z[$_]until$z[0]%$_}2,3,5
METHINKS IT IS A WEASEL (Nested Flatten)
やればできる子でした<Vim
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
:function! s:Random(n)
: if has('win32')
:   let r = libcallnr("msvcrt", "rand", 0)
: else
:   let r = libcallnr("libc", "rand", 0)
: endif
: return r % a:n
:endfunction

:function! s:MakeRandom()
: let res = ''
: for i in range(strlen(s:goal))
:   let res = res . nr2char(char2nr('A')+s:Random(26))
: endfor
: return res
:endfunction

:function! s:CheckScore(line, goal)
: let score = 0
: for i in range(strlen(a:goal))
:   let a = char2nr(strpart(s:goal,i,1))
:   let b = char2nr(strpart(a:line,i,1))
:   let d = a < b ? b - a : a - b
:   let score = score + d
: endfor
: return score
:endfunction

:function! s:SortLines(num)
: for i in range(a:num)
:   let line = getline(i+1)
:   let score = s:CheckScore(line, s:goal)
:   let line = printf("%05d:%s", score, line)
:   call setline(i+1,line)
: endfor
": %!sort
: let lines = sort(getline(1,a:num))
: for i in range(a:num)
:   call setline(i+1,strpart(lines[i],6,strlen(s:goal)))
: endfor
:endfunction

:function! s:ChangeLine(line_num, idx_num, var_num)
: for i in range(a:line_num)
:   let line = getline(i+1)
:   for j in range(a:var_num)
:     let vline = line
:     for k in range(a:idx_num)
:       let split_idx = s:Random(strlen(s:goal))
:       let head = strpart(vline,0,split_idx)
:       let tail = strpart(vline,split_idx+1,strlen(s:goal))
:       let vline = head .nr2char(char2nr('A')+s:Random(26)) . tail
:     endfor
:     call setline(a:line_num*(j+1)+i,vline)
:   endfor
: endfor
:endfunction

:let s:initial_line_num = 300
:let s:change_idx_num = 1
:let s:variaty_num = 5
:let s:goal = "METHINKSITISAWEASEL"

:let s:start_time = localtime()
:new
:for s:i in range(s:initial_line_num)
: call setline(s:i+1, s:MakeRandom())
:endfor
:call s:SortLines(s:initial_line_num)

:let s:break_flag = 0
:while s:break_flag == 0
: call s:ChangeLine(s:initial_line_num,s:change_idx_num,s:variaty_num)
: call s:SortLines(s:initial_line_num * s:variaty_num)
: let s:line = getline(1)
: if s:line ==# s:goal
:   let s:break_flag = 1
: endif
: echo getline(1)
:endwhile
:1
:let s:end_time = localtime()
:call append(0, (s:end_time - s:start_time) . " seconds elapsed")
LL Golf Hole 8 - 横向きのピラミッドを作る (Nested Flatten)
g++ 3.4.5 (mingw) や 4.1.2 、Sun C++ 5.8 で試してみましたが、
3行目4行目(関数の返値型省略)がerrorになってコンパイルできませんでしたよー
起動オプションの解析 (Nested Flatten)
ちょうど、今日TwitterでBoost.Program_optionsの話題が出てたとこでした。
なんというタイミング。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream>
#include <vector>
#include <string>
#include <exception>

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>

int main(int c, char**v)
{
  try {
    namespace po = boost::program_options;

    int debug;

    po::options_description desc("Options");
    desc.add_options()
      ("output,o", "output flag [required]")
      ("quote,q", "quote flag")
      ("debug,d", po::value< int >(&debug)->default_value(0), "debug level [0|1|2]")
      ;
    po::options_description hidden("hidden optionis");
    hidden.add_options()
      ("input", po::value< std::vector< std::string > >(), "input file [at least one required]")
      ;

    po::positional_options_description positional;
    positional.add("input", -1);

    po::options_description visible("Allowed Options");
    visible.add(desc);

    po::options_description full("Full Options");
    full.add(desc).add(hidden);

    po::variables_map vm;
    po::store(po::command_line_parser(c, v).options(full).positional(positional).run(), vm);
    po::notify(vm);    

    bool error=false;
    if ( !vm.count("output") ) {
      std::cerr << "*** you must specify -o option\n\n";
      error = true;
    }
    if ( !vm.count("input") ) {
      std::cerr << "*** you must specify at least 1 input parameter\n\n";
      error = true;
    }
    if ( debug < 0 || debug > 2 ) {
      std::cerr << "*** debug level must be 0, 1 or 2\n\n";
      error = true;
    }
    
    if ( error ) {
      std::cerr << visible << "\n";
      return 1;
    }

    bool output = vm.count("output");
    bool quote  = vm.count("quote");

    if ( output ) {
      std::cout << "[オプション情報]\n";
      std::cout << "o(output) : " << (output ? "ON" : "OFF") << "\n";
      std::cout << "q(quote)  : " << (quote  ? "ON" : "OFF") << "\n";
      std::cout << "d(debug)  : " << debug << "\n\n";

      std::cout << "[パラメタ情報]\n";
      const std::vector<std::string>& input = vm["input"].as< std::vector<std::string> >();
      std::cout << "指定数 : " << input.size() << "\n";
      for ( int i = 0; i < input.size(); ++i )
        std::cout << i+1 << " : " << (quote?"\"":"") << input[i] << (quote?"\"":"") << "\n";
    }

    return 0;
  } catch (const std::exception& e) {
    std::cerr << e.what() << "\n";
    return -1;
  }
}
LL Golf Hole 9 - トラックバックを打つ (Nested Flatten)
お題がGolf向けじゃないとか..

後、さすがに一行では表示がえらいことになるので、適当に改行
1
2
3
4
5
use LWP::UserAgent;
print LWP::UserAgent->new->post(
  'http://ll.jus.or.jp/2008/blog/archives/38/trackback',
  {qw{blog_name LLGolfHole9 title llfuture url http://ja.doukaku.org/207
    excerpt LLGolf最終ホールを打ってみた}})