Unknown::Programming このページをアンテナに追加 RSSフィード

2007-05-10 解析

Web::Scraper使ってみた

id:naoyaさんが触ってるの見て面白そうなので僕も触ってみました。

Web::Scraper - naoyaのはてなダイアリー

で何を取得してこよーかなーと思ったんですが、ちょーど今流行り?のFizzBuzz問題でブクマコメントワンライナー大会になってるのでコード(っぽい)ものを取って来るやつを作りました。


#!/usr/bin/perl
use strict;
use warnings;

use Web::Scraper;
use Encode;
use URI;
use URI::Find;
use Perl6::Say;

my $url = 'http://b.hatena.ne.jp/entry/http://www.aoky.net/articles/jeff_atwood/why_cant_programmers_program.htm';

my $links = scraper {
    process 'span.comment', 'comment[]' => 'TEXT';
    result 'comment';
}->scrape(URI->new($url));

for my $comment ( @$links ) {
    next unless $comment;
    my $hcomment = $comment;
    URI::Find->new( sub { '' } )->find(\$hcomment);
    if ( $hcomment =~ /[\s\x20-\x7e]{30}/ ) {
        say encode('shiftjis', $comment)."\n";
    }
}

コメントの内容が30文字以上のURLでないアスキー文字列だったらマッチという若干ゴリ押しの実装になってます。

で実行結果


php -r 'while($i++<100){$s=$i%3?"":"Fizz";$s.=$i%5?"":"Buzz";echo ($s?$s:$i)."\n";}' //可読性も考えて、こんなか?

1.upto(100){|i|s=((i%3==0)?"Fizz":"")+((i%5==0)?"Buzz":"");p((s=="")?i:s)}で74byte

vimで。i1<esc>qxYp<Ctrl-A>q98@x3GqxSFizz<esc>3jq32@x5Gqx:s/\d*$/Buzz<LR>5jq18@x

0byte -> perl -MAcme::FizzBuzz -e ''

phpの最短はこれかなあ。初期化はしとく方向で。php -r 'for($i=0;$i++<100;)echo($i%15?$i%3?$i%5?$i:'Buzz':'Fizz':'FizzBuzz')."\n";'

pythonで。for i in range(1,101):print"Fizz"*(i%3<1)+"Buzz"*(i%5<1)or i http://d.hatena.ne.jp/tenkoma/20070509/1178717333

 目指せ最短(56byte) perl -e'die+map{(Fizz)[$_%3].(Buzz)[$_%5]||$_,$/}1..1e2'

n=101;m=[''];for(i=1;i<n;i++)m[i]=i;for(i=3;i<n;i+=3)m[i]='Fizz';b='Buzz';for(i=5;i<n;i+=5)if(m[i]!=i){m[i]+=b}else{m[i]=b};m.join('%20')とかa=[3,,,1,,2,1,,,1,2,,1];b=['','Fizz','Buzz'];s='';for(i=j=1;i<101;i++,j++){if(14<j)j=0;c=a[j];s+=((c)?(b[c&1]+b[c&2]):i)+'%20'};sとかorz

とりあえず2分とか時間短縮を目指すならこれじゃいかんの? printf("1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,11,Fizz,13,14,FizzBuzz,16,17,・・・")

rubyで剰余なし:(1..100).zip(['','','Fizz']*34,(['']*4<<'Buzz')*20).each{|i|/\d+$|\D+/=~i.to_s;puts$&}

php -r 'for($i=1;$i<=100;$i++)echo(!($i%3)?(!($i%5)?"FizzBuzz":"Fizz"):(!($i%5)?"Buzz":$i))."\n";'

C言語で無理矢理。。。#include<stdio.h>#include<stdlib.h>void main(void){int i;char c[4];for(i=1;i<101;i++) printf("%s\n",i%15?i%5?i%3?itoa(i,c,10):"Fizz":"Buzz":"FizzBuzz");}

BASICで7分もかかった・・・For a=1 To 100:If a Mod 15=0 Then Print "FizzBuzz" Else:If a Mod 3=0 Then Print "Fizz" Else:If a Mod 5=0 Then Print "Buzz" Else:Print a: Next a

ほぼ限界の108byte。。class M{static{for(int i=0;++i<101;)System.out.println(i%15==0?"FizzBuzz":i%3==0?"Fizz":i%5==0?"Buzz":i);}}

ruby -e '(1..100).each{|n|s="";s+="Fizz"if n%3==0;s+="Buzz"if n%5==0;puts s==""?n:s}'

perl -e 'print $_ % 15 == 0 ? "FizzBuzz\n" : $_ % 5 == 0 ? "Buzz\n" : $_ % 3 == 0 ? "Fizz\n" : "$_\n" for 1 .. 100'

(use srfi-42)(list-ec(: i 1 101)(case(modulo i 15)((0)’FizzBuzz)((3 6 9 12)’Fizz)((5 10)’Buzz)(else i)))

for(int i=1;i<=100;i++){if((i%3)&&(i%5))cout<<i;else{if(!(i%3))cout<<"Fizz";if(!(i%5))cout<<"Buzz";}cout<<endl;}

剰余を使わないって一般的にどうやるんでしょうか? javascript:(function(){var i=j=k=0,s=[];while(i++<100)s.push((++j==3?(j=0,'Fizz'):'')+(++k==5?(k=0,'Buzz'):'')||i);alert(s)})() あんまsmartじゃない/↑neokun それで2分切れたら逆にスゴイよw

char flag[15]={0,0,1,0,2,1,0,0,1,2,0,1,0,0,3};char *fb[4]={"%d\n","Fizz\n","Buzz\n","FizzBuzz\n"};for(int i=1;i<=100;i++)printf(fb[flag[i%15,i); 別解: Google:fizzbuzz.c

for(StringBuffer p,i = new StringBuffer();i.length()<100&&((p=new StringBuffer())!=null)&&i.append(" ")!=null;System.out.println(p.append(i.length()%3==0?"Fizz":"").append(i.length()%5==0?"Buzz":"").append(p.length()==0?i.length():""))){}

gawk -v i=0 'BEGIN {while(++i<101)print(i%15?i%5?i%3?i:"Fizz":"Buzz":"FizzBuzz")}'

i%3==0 then s="Fizz" elsif i%5==0 then s="Buzz" end; puts s end' ←長いなー

だいぶ縮んだ。133バイトまで,あと2バイト class F{public static void main(String[]a){for(int i=0;++i<101;)System.out.println(i%15<1?"FizzBuzz":i%5<1?"Buzz":i%3<1?"Fizz":""+i);}}

void f(int i, int m){ if(i>=m) return; else if((i%15)==0)printf("FizzBuzz"); else if((i%5)==0)printf("Buzz"); else if((i%3)==0) printf("Fizz"); else printf("%d",i); f(i+1,m); } int main() {f(1,100); } 意外と長くなった。普通にループの方が短い?

perl -MPerl6::Say -e"say(!($_%15)?FizzBuzz:!($_%3)?Fizz:!($_%5)?Buzz:$_)for(1..100)"

awk 'BEGIN { for(i=1;i<=100;i++) { s=""; if(!(i%3)) s=s "Fizz"; if(!(i%5)) s=s "Buzz"; print s ? s : i; } }'

(Haskellで99byte) main=mapM_(putStrLn.z)[1..100];a%b=mod a b==0;z n|n%15="FizzBuzz"|n%3="Fizz"|n%5="Buzz"|True=show n

print"$_\r",$_%3?'':Fizz,$_%5?'':Buzz,"\n"for 1..100 イカサマっぽいし潜在バグ持ち。/最短をぐぐって絶望。真っ当な改行つきで48バイト……。

main=mapM(putStrLn.z)[1..100]where z a|p 15="FizzBuzz"|p 5="Buzz"|p 3="Fizz"|True=show a where p x=mod a x==0 …勉強中の身です。うわぁ願い下げられてる…↓許してください><

 最短→ javascript:open('http://hamachiya.com/fb') / ちゃんとかいた→ javascript:x=i='';while(++i<101)x+=(i%5|i%3?i%3?i%5?i:'Buzz':'Fizz':'FizzBuzz')+' ';x

ruby -e "p (1..100).to_a.map {|i| i % 15 == 0 ? 'FizzBuzz' : i }.map {|i| i % 3 == 0 ? 'Fizz' : i }.map {|i| i % 5 == 0 ? 'Buzz' : i }"

 var ret =[];for(var i=1;i<=100;i++){ret.push(i%15===0 ? 'FizzBuzz' : i%3===0 ? 'Fizz' : i%5===0 ? 'Buzz' : i)};ret.join('\n');

確認だけど、2分以内にできるのが200人に1人ってことだよね? / 標準unixコマンドを混ぜてよければ「seq 100|perl -ple '$_=($_%3?"":Fizz).($_%5?"":Buzz)||$_'」で56bytes。/ http://golf.shinh.org/p.rb?FizzBuzz も参照。

ruby -e "1.upto(100) {|i| puts i % 15 == 0 ? 'FizzBuzz' : (i % 5 == 0 ? 'Buzz' : (i % 3 == 0 ? 'Fizz' : i))}"

Gauche:(use srfi-42)(map(lambda(x)(let1 % (lambda(y)(= 0 (remainder x y)))(cond((% 15) 'FizzBuzz)((% 5)'Buzz)((% 3)'Fizz)(0 x))))(list-ec(: i 100)(+ i 1)))

((lambda (n) (define (f n a) (cond ((= n 0) a) ((= (modulo n 15) 0) (f (- n 1) (cons "FizzBuzz" a))) ((= (modulo n 3) 0) (f (- n 1) (cons "Fizz" a))) ((= (modulo n 5) 0) (f (- n 1) (cons "Buzz" a))) (else (f (- n 1) (cons n a))))) (f n '())) 100)

 javascript:(function(d,i){while(i++<100)d+=(i%15?i%5?i%3?i:'Fizz':'Buzz':'FizzBuzz')+' ';alert(d)})('',0) / Point:var文面倒→仮引数、"==0"→boolean型変換、"for(i=0;i<=100;i++)"→"while(i++<100)"(i=0は仮引数で)

(loop for i from 1 to 100 do(print(or(cadr(assoc i'((15 "FizzBuzz")(3 "Fizz")(5 "Buzz")):test(lambda(x y)(= 0(mod x y)))))i)))

関数modを使わない場合. 要改行 Fortran77 do i=1,100 j=i/15 k=i/5 m=i/3 if(j*15 .eq.i)then write(6,*)'FizzBuzz' elseif(k*5 .eq.i)then write(6,*)'Buzz' elseif(m*3 .eq.i)then write(6,*)'Fizz' else write(6,*)i endif enddo stop end

#include<stdio.h>main(){int j=0,k=1;while(k<101){if(k==k/3*3){printf("Fizz");j++;}if(k==k/5*5){printf("Buzz");j++;}if(j==0)printf("%d",k);printf("\n");j=0;k++;}}

for(i=1;i<=100;i++){console.log(i%15==0 ? "FizzBuzz" : (i%3==0 ? "Fizz" : (i%5==0 ? "Buzz" : i)));}

みんなエレガントだなぁ for(1..100){unless($_%3 || $_%5){print "FizzBuzz\n";}elsif($_%3 == 0){print "Fizz\n";}elsif($_%5 == 0){print "Buzz\n";}else{print $_;print "\n";}

ブコメだと半角[[が消える? / ruby -e "require 'generator';proc{|c,a|m=a.map{|n,s|Generator.new{|g|loop{n.times{|i|g.yield((i == n-1)?s:'')}}}};c.times{|i|s=m.map{|g|g.next}.join;puts s.empty? ? i+1:s}}.call 100,[ [3,'Fizz'],[5,'Buzz'] ]"

佐野さんの添削により改良 ((lambda (n) (define (i n a) (if (= n 0) a (i (- n 1) (cond ((= (remainder n 15) 0) (cons 'FizzBuzz a)) ((= (remainder n 3) 0) (cons 'Fizz a)) ((= (remainder n 5) 0) (cons 'Buzz a)) (else (cons n a)))))) (i n '())) 100)

perl -e 'for(1..100){print;print"\b\b\bFizz "if$_%3==0;print"\b\b\bBuzz"if$_%5==0;print"\n"}' 三項演算子抜きはつらいな。/1行40文字だと思ってたら100文字までいけたのか。収めるために削った時間が無駄になったな。

 python -c 'print "\n".join("".join(k * (i % j == 0) for j, k in [(3, "Fizz"), (5, "Buzz")]) or str(i) for i in range(1, 101))'

Javaで適当に書いてみたが下の人たちのスマートさに嫉妬 public class FizzBuzz{public static void main(String[] args){for(int i=1; i<=100;i++){if(i%3>0 && i%5>0) System.out.print(i+" ");if(i%3==0) System.out.print("Fizz ");if(i%5==0) System.out.print("Buzz ");}}}

javascript:var c="";var t;var f;var n=1;while(n<=100){t=n%3;f=t%5;if(t==0){c+="Fizz";}if(f==0){c+="Buzz";}if(t*f!=0){c+=n;}n++;c+="\n";}alert(c); みんな凄すぎ、、、

php -r 'while($i<100)echo ++$i%15?($i%5?($i%3?"":"Fizz\n"):"Buzz\n"):"FizzBuzz\n";'

perl -le 'print $_%15?$_%5?$_%3?$_:Fitz:Brad:FitzBrad for(1..100)'

<?php for ($i=1; $i < 101; $i++) { if ($i % 3 == 0) echo "Fizz"; if ($i % 5 == 0) echo "Buzz"; if (($i % 3 != 0)&&($i % 5 != 0)) echo $i; echo "\n"; } ?>・・・美しくないなorz

ruby -e '(1..100).each{|i|print i%15==0?"FizzBuzz":i%5==0?"Buzz":i%3==0?"Fizz":i,"\n"}' ちなみに最短はこうらしい→ 1.upto(?d){|i|i%3<1&&x=:Fizz;puts i%5<1?"#{x}Buzz":x||i}

 perl -le 'print $_%15?$_%5?$_%3?$_:Fizz:Buzz:FizzBuzz for(1..100)'

javascript:function f(){var d='';for(i=1;i<101;i++){d+=i%2515==0%3f'FizzBuzz':i%255==0%3f'Buzz':i%253==0%3f'Fizz':''+i;d+=' ';}return d;}document.body.innerHTML=f(); アドレスバー用

pugs -e "(1..100).map:{ $_ % 15 ?? $_ % 5 ?? $_ % 3 ?? $_ :: 'Fizz' :: 'Buzz' :: 'FizzBuzz' }.join(qq{\n}).say" / Perl6がなかったので追加してみた / ↑id:yappoさん perl -MAcme::FizzBuzz -e 0 で-1byte

最短を目指してみる。perl -le 'print(($_%3?"":Fizz).($_%5?"":Buzz)or$_)for 1..100'/これっぽい→perl -le 'print"$_\r",$_%3?"":Fizz,$_%5?"":Buzz for 1..100'なるほどなあ

FizzBuzzを晒すの流行ってるの?▲で改行。プリプロセッサ文のone-liner化は知らん。 #include<iostream>▲#include<sstream>▲main(){bool f,b;for(int i=1;i<101;i++){std::stringstream s;if(f=i%3==0)s<<"Fizz";if(b=i%5==0)s<<"Buzz";if(!b&&!f)s<<i;std::cout<<s.str()<<std::endl;}}

php -r 'for ($i=1;$i<101;$i++) echo $i%15?($i%5?($i%3?$i . "\n":"Fizz\n"):"Buzz\n"):"FizzBuzz\n";'

 日本だと事情が違いそう/Fizz-Buzz問題/php -r 'while(@++$i<101)echo($i%15?$i%5?$i%3?$i:@Fizz:@Buzz:@FizzBuzz)."\n";'

とりあえずJavaで工夫のないコード:class FizzBuzz{public static void main(String[] a){for(int i=1;i<101;i++)System.out.println(i%15==0?"FizzBuzz":i%3==0?"Fizz":i%5==0?"Buzz":""+i);}}

ちゃんと全部確認はしてないけど多分取れてると思う。

あとはこれをコードから言語を割り出してカテコライズできればいいんだけどさすがにそこまではorz

ってかWeb::Scraperめちゃくちゃ便利だコレ。

追記:2007/05/11

id:miyagawaさんからTB頂きました

最後のforの部分をコールバックですっきり書くとことができるみたいです↓

Web::Scraper 勝手に添削 - Bulknews::Subtech - subtech

Connection: close