はてなキーワード: argvとは
import json import urllib.request # True にするとユーザー名を隠す hide_user = False # 以下を書き換える。sys.argv 使ってもいいんだけど url1 = "https://www.cygames.co.jp/news/id-23172/" url2 = "https://mtg60.com/archives/palworlddoujinsi.html" def get_bookmarks(url: str): req = urllib.request.Request(f"https://b.hatena.ne.jp/entry/json/{url}") with urllib.request.urlopen(req) as res: dict = json.loads(res.read()) user_comments = {} for bookmark in dict["bookmarks"]: if bookmark["comment"]: user_comments[bookmark["user"]] = bookmark["comment"] return user_comments b1 = get_bookmarks(url1) b2 = get_bookmarks(url2) common = set(b1.keys()).intersection(b2.keys()) print(f"[1] {url1}") print(f"[2] {url2}") print() for user in sorted(common): if hide_user: print(user[0] + "*" * (len(user) - 1)) else: print(user) print(f"[1] {b1[user]}") print(f"[2] {b2[user]}") print()
僕はプログラミング歴2週間の初心者です。キーと値を入力できるデータベースを作っています。
以下のコードを実行してデータを追加し続けると、一定のサイズを超えるとエラーが出てしまうみたいです。
理想は、データが追加された後にサイズが足りなくなったら動的に自動拡大されることです。
もし詳しい人がいたらご教示お願い致します。
import sys import os import mmap import hashlib def h(x): return int(hashlib.sha512(x.encode()).hexdigest(), 16) def create_db(filename): with open(filename, 'wb') as f: f.write(b'\0' * 1024 * 1024) # 1MBの空ファイルを作成 def set_key(filename, key, value): with open(filename, 'r+b') as f: mm = mmap.mmap(f.fileno(), 0) pos = h(key) % mm.size() while mm[pos:pos+1] != b'\0': pos = (pos + 1) % mm.size() if pos == h(key) % mm.size(): f.seek(0, os.SEEK_END) f.write(b'\0' * mm.size()) # ファイルサイズを2倍にする mm = mmap.mmap(f.fileno(), f.tell()) # ファイルサイズを反映させる pos = h(key) % mm.size() # ハッシュ値を再計算する data = key + '\0' + value + '\0' data = data.encode() mm[pos:pos+len(data)] = data mm.close() # mmapオブジェクトを閉じる def get_key(filename, key): with open(filename, 'r+b') as f: mm = mmap.mmap(f.fileno(), 0) pos = h(key) % mm.size() while mm[pos:pos+1] != b'\0': end = mm.find(b'\0', pos, mm.size()) # 第2引数と第3引数を指定する if end == -1: end = mm.size() if mm[pos:end].decode() == key: pos = end + 1 end = mm.find(b'\0', pos, mm.size()) # 第2引数と第3引数を指定する if end == -1: end = mm.size() value = mm[pos:end].decode() mm.close() # mmapオブジェクトを閉じる return value pos = (pos + 1) % mm.size() if pos == h(key) % mm.size(): break mm.close() # mmapオブジェクトを閉じる return None def main(): cmd = sys.argv[1] if cmd == 'create': create_db(sys.argv[2]) elif cmd == 'set': set_key(sys.argv[2], sys.argv[3], sys.argv[4]) elif cmd == 'get': print(get_key(sys.argv[2], sys.argv[3])) if __name__ == '__main__': main()
https://github.com/kokorohamoe/OpenProfile/blob/master/700_sample/Java/Jurina/reader.cpp
int main(int argc,const char*argv[]){
int v;
char buffer[1024];
while(1){
printf("input\n");
scanf("%s%d",buffer,&v);
if(strcmp(buffer,"print")==0)
fprintf(stderr, "public class base{\n"
"public static void main(String[] args){\n"
"int i = %d;\n"
"System.out.println(i);}}\n",v);
}
return 0;
}
昔の職場は、Cで引数を見るときにargv[]にNULLが入ってるかどうかで引数の数を判定してたりした。
int main(int argc, char*argv[])
{
for (・・・) {
if (argv[i] == NULL) // 引数の終わりの判定
}
}
それがバグることがあったので、普通にargcを見るようにして「デバッグしました、原因はコレコレです」と報告したら「よくそんなの分かったな」と感心されたことがあった。
個人的には、それまで本やコードで、引数の数をargc以外で判定してるコードを見たことなかったから、その職場のコードを見て新鮮な驚きがあったんだけど。
「独学でかじってるやつは変な癖がついてダメだ。使えない。なにも知らない新人のほうが素直で延びる」とか言ってる人をたまに見るけど、ネットや本で勉強しないで、職場で教えてもらうだけのほうがむしろ変な癖がつきやすいと思うわ。
たすけてね☆ このままだと ころされちゃう あいてにそんなつもりがなくても
あいてがやることは はなしかけるだけ ただし 不用意なタイミングで 何年も
それだけで 殺せるかの 実験でも しているんだろう
そんなものをうけたつもりはないし 顔合わせもしていない
また、そういう事故とまちがえられないよう 最近はAKBのイベントなども すべて自粛しているこ
困りぬいた人に
こっちが 入院になった
そういうことしかない
国に助けてもらいたい だれもいないから 天涯孤独 それもだめなら どこがいいか?
周囲の人からは理由は特にないけど なぜか いじめられることはおおい
っておもしろい
いままで、誰かの準備を食ってきたからかんたんだったんじゃない?
よく食われるからそうおもう
くうこと(きがつかずにもらっちゃう)もあるけどね
わからない
いまのたんとうが過去の中ではけっこういい
はなしかけられる ということがどれだけ苦痛を伴うかは だいぶまえから知ってる
がいきちの話を聞くのは苦痛だろう
それがわかるから、なるべくしないようにしている
でも限界なんだ
ここにひたすらかいていると すこしだけおちつく。
基本書き込んでいる間はプログラムを組んでいることが大多数
またさぎょう。
ずっといえだから、気がつくと寝ている。
あさおきると作業再開
ひたすら作業
みーんななくなっちゃうね
あそぶまえに とられて おわる まぁ コロナはしょうがないけど
としくったなぁとおもった
*調子に乗るな!って
ヒット作もない
簡単にクビになる
いらねー人材
そんなもん、じぶんが、いちばんよくしってる
いっしょけんめいがんばって
ねたみ そねみ 誹謗中傷はやまもど
ちょうしになどのれない
いじめられこそすれ いいことなどないのは自分が一番良く知っている。
くつなめましょうか?
血反吐は吐いてないけど
苦労して、苦労して つくってる
そうだろうなとおもう
あいての言い分を聞いて それこそ おれが 死んでりゃよかったんだろうなと思った
せめても がんばったから
がんばったといっただけだけど
ちょうしにのるな というのなら のらないし 乗る理由など無い
イラッとしたからAKBのCDでも買って送りつけてやりたい もちろん持ってるやつを
あとでいく
#include <iostream> #include <stdio.h> int main(int argc,char *argv[]){ for(int i=0;i<3;++i){ int j = i; printf("Hello world%d92;r92;n",j); } for(int i=0;i<0;++i){ printf("Hello again92;r92;n"); } return 0; };
それで十分だった
がんばったんだ。貯金500万
あっというまに、なくなっちゃった。
もう戻らない僕の幸せ
呪われていて
親が転校してくれたけど
だめだった ばかだったんだ
がんばっても だめなら
それはそれでいい
1. こんな感じで使います。
$ python parser.py sample.py
import parser code = ''' a = 1 + 1 print(a) ''' graph = parser.create_graph(code) graph.render("sample")
import ast import sys import graphviz def create_graph(lines): graph = graphviz.Graph(format='png') root = ast.parse(lines) node_list = [root] _setup(graph, node_list) return graph def _setup(graph, node_list): # node node = node_list[-1] node_identity = str(len(node_list)) node_name = type(node).__name__ graph.node(node_identity, node_name) # children for child in ast.iter_child_nodes(node): node_list.append(child) child_identity = str(len(node_list)) graph.edge(node_identity, child_identity) _setup(graph, node_list) if __name__ == '__main__': file_name = sys.argv[1] with open(file_name) as file: lines = file.read() graph = create_graph(lines) graph.render(file_name)
一応想定してる答えのコードは↓(再帰で書くと途中でメモリ足りなくなるから満点取れないと思う)だとおもうんだけど、
やっぱ答えは3なのでなんかおかしい。運営問い詰めるか問題文全部載せな。
<?php $X = $argv[1]; $sai=[1,2,3,4,5,6]; function sai($find,$table=[ 1=>[1], 2=>[2], 3=>[3], 4=>[4], 5=>[5], 6=>[6] ], $try=1){ echo "TRY = $try \n"; if(array_key_exists($find,$table)){ var_dump($table); return $try; } $result=[]; foreach($table as $goukei=>$mens){ $mens=array_merge( array_reduce($mens, function($carry,$item){ return array_merge($carry,draft($item)); },[]) ); foreach($mens as $me){ if(empty($result[$goukei+$me])){ $result[$goukei+$me]=[]; } if(!in_array($me,$result[$goukei+$me])){ $result[$goukei+$me][]=$me; } } } $keys=array_keys($result); sort($keys); for($i=count($keys)-1;0<=$i &amp;&amp; 20 < $i ;$i-- ){ unset($result[$keys[$i]]); } return sai($find,$result,$try+1); } function draft($k){ return array_filter(master(), function($me) use($k) { return ($k!=$me) &amp;&amp; ($k+$me) !=7; } ); } function master(){ return [1,2,3,4,5,6]; } echo "RESULT!".sai($X); ||<
相変わらず投稿するような場を持ってないのでここに。
PyQt5のアプリ上で外部から取得したPNG/JPEGをクリップボードに送りたかったが、
期待する動作は、Officeに元の形式として貼り付け可能であること。
QClipboardなのかclipboardなのかで相当手間取った。
というかQApplicationがいまいちわからん。これでいいのだろうか。
ともあれ、クリップボードにはいろいろ格納されたようだが、Office上ではビットマップとしてしか貼り付けられなかった。
import sys from PyQt5.Qt import QApplication, QImage img = QImage('test.png') app = QApplication(sys.argv) app.clipboard().setImage(img)
失敗1から一回QMimeDataを経由してみた。結果何も変わらず。
# -*- coding: utf-8 -*- import sys from PyQt5.Qt import QApplication, QImage, QMimeData img = QImage('test.png') data = QMimeData() data.setImageData(img) app = QApplication(sys.argv) app.clipboard().setMimeData(data)
以前C#にて、画像生成してクリップボードに送るアプリを作ろうとしていたときの残骸を参考にトライ。
無事期待する動作が得られた。
JPEGの場合はsetData('JFIF', img)になる。
# -*- coding: utf-8 -*- import sys from PyQt5.Qt import QApplication, QMimeData with open('test.png', 'rb') as fo: img = fo.read() data = QMimeData() data.setData('PNG', img) app = QApplication(sys.argv) app.clipboard().setMimeData(data)
今回はPyQt5ベースだったので試さなかったが、pywin32のwin32clipboardとかいうのも使えたのだろうか。
Excelを持っているならはてブのJSONデータをそのまま取り込めるそうだからそのデータを使ってブクマが付いた時間のグラフが描けそう。
例えばこんな感じでJSONデータが取れる。 http://b.hatena.ne.jp/entry/jsonlite/https://anond.hatelabo.jp/20180315232737
Excel持ってないならスクリプトでCSVにしてしまえばいい。
rubyスクリプトだとこんな感じ。(Mechanize無し版に差し替え。なぜMechanizeを使っていたかと言うとはてブがUser-Agentが空だと値を返してくれないから。ちょっと長くなるが自前でUAを渡すようにした。)
#!/usr/bin/ruby
site = ARGV[0]
json_uri = URI.parse("http://b.hatena.ne.jp/entry/jsonlite/%s" % [site])
response = Net::HTTP.start(json_uri.host, json_uri.port) do |http|
http.get(json_uri.path, "User-Agent" => "Mozilla/5.0")
end
json_data = JSON.parse(response.body)
json_data['bookmarks'].each do |bookmark|
puts [bookmark['user'], bookmark['timestamp'], bookmark['comment'], bookmark['tags'].to_s].to_csv
end
引数に取得したいページのURLを入れる。hatebuapi-csv.rbという名前で保存したとしたらこんな感じで実行。
% hatebuapi-csv.rb https://anond.hatelabo.jp/20180315######## > 結果.csv
... | fun x:: cmd1 x : cmd2 x : ... : cmdn x | ...
一行毎に処理する場合はxargs -Iを利用する。
$ ls *txt a.txt b.txt $ cat a.txt 1 $ cat b.txt 2 $ ls *txt | fun x:: echo x : cat x a.txt b.txt 1 2 $ ls *txt | xargs -Ix fun _:: echo x : cat x a.txt 1 b.txt 2
>と<はそれぞれ大小の不等号で置き換えてくださいな
#!/usr/bin/env python import sys from subprocess import * def take_variable(var): # check the syntax of variable (http://www.gnu.org/software/bash/manual/bash.html) # variable ::= (_|[A-z])(_|[A-z]|[0-9])* # variable contained space if len(var.split()) > 1: raise Exception('fail: the variable contained space') # check head if not (var[0].isalpha() or var[0] == '_'): raise Exception('fail: the variable contained wrong character') # check the body of variable b = True i = 0 for c in var[1:]: i += 1 # is variable contained invalid character? if not (c.isalpha() or c.isdigit() or c == '_'): b = False break # no exception if thre are only spaces after variable if not b and not var[i:].isspace(): raise Exception('fail: the variable contained wrong character') elif b: return var[0] else: return var[:i] def parse(var_to_cmds): # check the position of '::' try: pos = var_to_cmds.index('::') except Exception: raise Exception('not exists "::"') var = var_to_cmds[:pos] cmd_str = var_to_cmds[pos+2:] # check the format of variable and commands if var == '': raise Exception('fail: no variable before "::"') elif cmd_str == '': raise Exception('fail: no commands after "::"') return (take_variable(var),cmd_str) if __name__ == '__main__': # parse variable and commands try: var,cmd_str = parse(' '.join(sys.argv[1:])) except Exception, e: print >>sys.stderr, e sys.exit(1) # var -> val val = sys.stdin.read().replace('\n',' ') # mapping and split by ':' again commands = map( (lambda cmd: cmd.replace(' '+var+' ',' '+val+' ')), cmd_str.split(':')) # exec command for cmd in commands: try: # need split for remove spaces check_call(cmd.split()) except Exception,e: # print >>sys.stderr, e sys.exit(1)
本当はfunじゃなくて\(バックスラッシュ)で、:: じゃなくて→にしたかったんだけど、シェルが置き換えちゃうからしかたない
シェルの改造は禁断の手段だし
じゃぁ、問1をやってみた。
unsigned int f(unsigned int x) { x = x - 1; x = x | (x >> 1); x = x | (x >> 2); x = x | (x >> 4); x = x | (x >> 8); x = x | (x >>16); return x + 1; } int main(int argc, const char * argv[]) { int check = 1; int cnt=0; if(0!=f(0)){ cnt++; } for(unsigned int i=1;i!=0;i++){ if(check < i){ check <<=1; } if(check != f(i)){ cnt++; } if(i%0x10000==0){ printf("%x\n",i); } } printf("cnt=%d\n",cnt); return 0; }
iよりも等しいか大きい最小の2の乗数
書いてみたけどぜんぜん面白くならんわ。このサイズで面白さを競ってもなあ。
どうやったら面白くなる?
#include "stdafx.h" #include "windows.h" int _tmain(int argc, _TCHAR* argv[]) { int i=2; int j=0; while(1){ i++; for(j=2;j<i;j++){ if((i % j)==0){ //printf("%d は素数ではない\n",i); break; } } if(j==i){ //printf("%d は素数\n",i); printf("%d\n",i); } //Sleep(1000); } return 0; }
if も 3項演算子も for も do whileすらもない ifなしの Fizz Buzz
#include "stdio.h" #include "stdlib.h" int cnumber=0; void fizz(){ printf("fizz"); cnumber++; }; void nonfizz(){ }; void buzz(){ printf("buzz"); cnumber++; }; void nonbuzz(){ }; void number(int i){ printf("%d",i); cnumber = 0; } void nonnumber(int i){ cnumber = 0; } void myexit(void){ printf("\n Hit return key to exit\n"); getchar(); exit(1); } void noexit(void){ } void (*pfizz[3])() = {fizz,nonfizz,nonfizz}; void (*pbuzz[5])() = {buzz,nonbuzz,nonbuzz,nonbuzz,nonbuzz}; void (*pnumber[3])(int) = {number,nonnumber,nonnumber}; void (*pmyexit[2])() = {noexit,myexit}; int main(int argc, char* argv[]) { int loopmax = (111+222+333)*10; int i = 1; head: (*pfizz[i%3])(); (*pbuzz[i%5])(); (*pnumber[cnumber])(i); (*pmyexit[!(loopmax-i)])(); printf(","); i++; goto head; return 0; }
includeが<>を使ってないので必要ならパスは各自で通してねw
10/18 改訂
なお、取得した画像の著作権はグーグル他各社が保持しています。
ご利用は計画的に私的範囲でどうぞご利用ください。
#!/usr/bin/perl use strict; use warnings; use Getopt::Long; use LWP::UserAgent; use GD; my $cmdline = join(" ", $0, @ARGV); my $usage = "usage: $0 -sx=116423 -sy=51603 -ex=116426 -ey=51605 -dx=4 -dy=3 -z=17 -size=300 -get=30 -dir=cache -output=output.jpg -nodebug"; my ($sx, $sy) = (0, 0); my ($ex, $ey) = (0, 0); my ($dx, $dy) = (4, 3); my $z = 17; my $size = 300; my $get = 30; my $dir = "cache"; my $output = "output.jpg"; my $debug = 0; GetOptions("sx=i" => \$sx, "sy=i" => \$sy, "ex=i" => \$ex, "ey=i" => \$ey, "dx=i" => \$dx, "dy=i" => \$dy, "z=i" => \$z, "size=i" => \$size, "get=i" => $get, "dir=s" => \$dir, "output=s" => \$output, "debug!" => \$debug) or die "$usage\nDied"; if ($ex == 0) { $ex = $sx + $dx; } else { $ex++; $dx = $ex - $sx; } if ($ey == 0) { $ey = $sy + $dy; } else { $ey++; $dy = $ey - $sy; } $sx>0 and $dx>0 and $sy>0 and $dy>0 and $z>0 and $dir and $output or die "$usage\nBad arguments"; $dx*$dy > $size and die "Getting too large."; $debug and print "debug: mkdir $dir\n"; mkdir $dir; -d $dir or die "can't make dir $dir: $!"; my $base = sprintf("http://khm%d.google.co.jp/kh/v=46&z=%d", int(rand(4)), $z); my $ua = LWP::UserAgent->new; printf "now get %d images...\n", $dx*$dy; for (my $x=$sx; $x < $ex; $x++) { for (my $y=$sy; $y < $ey; $y++) { my $file = sprintf("%s/%02dz%06dx%06d.jpg", $dir, $z, $x, $y); $debug and print "debug: check of $file\n"; -s $file and next; --$get < 0 and last; my $req = HTTP::Request->new(GET=>+"$base&x=$x&y=$y"); $debug and print "debug: fetch from ".$req->uri."\n"; my $res = $ua->request($req); unless ($res->is_success) { print "fail fetch from $file: ", $res->status_line, "\n"; next; } if (open(my $fh, ">", $file)) { $debug and print "debug: write of $file\n"; binmode $fh; print $fh $res->content; close $fh; } else { print "fail open in $file: $!\n"; } } } $get < 0 and print "reach the getting limit, skip after all.\n"; printf "creating %dX%d image...\n", 256*$dx, 256*$dy; my $image = new GD::Image(256*$dx, 256*$dy); for (my $x=$sx; $x < $ex; $x++) { for (my $y=$sy; $y < $ey; $y++) { my $file = sprintf("%s/%02dz%06dx%06d.jpg", $dir, $z, $x, $y); $debug and print "debug: check of $file\n"; -s $file or next; $debug and print "debug: read of $file\n"; my $part = GD::Image->newFromJpeg($file); $debug and print "debug: image copy\n"; $image->copy($part, 256*($x-$sx), 256*($y-$sy), 0, 0, 256, 256); } } #$image->string(gdSmallFont, 0, 0, $cmdline, $image->colorAllocate(255, 255, 255)); open(my $fh, ">", $output) or die "fail open $output: $!"; $debug and print "debug: write of $output\n"; binmode $fh; print $fh $image->jpeg(); close $fh;
例えば秋葉原とか
perl gmwall.pl -sx=116423 -sy=51603 -ex=116427 -ey=51606
駅だけとか
perl gmwall.pl -sx=465701 -sy=206420 -ex=465705 -ey=206423 -z=19
使う数値はfirebugなどで拾ってください。
セキュリティ目的ではない。ハッシュテーブルで使うような奴でキャッシュで使いたい。
手軽なほうが良い。軽いほうが良い。推測可能でよい。数十バイトくらいの文字列にしたい。
md5が一番汎用っぽいけど、無駄に重い気がする。crc32は軽そうだしそれなりに汎用っぽいけど、ハッシュ長が短いのがめんどい。
調べた→ http://anond.hatelabo.jp/20090327015620
ベンチ用スクリプト
#!/usr/local/bin/python from sys import argv, stderr from time import time from string import ascii_letters, join from random import choice from hashlib import md5 from binascii import crc32 from itertools import izip time_fmt = '%10s: %5d ms' shift = int(argv[1]) if len(argv)>1 and argv[1].isdigit() else 2 length = 0x100 << shift cycle = 0x10000 >> shift print >> stderr, 'string length: 0x%x, cycle: 0x%x' % (length, cycle) data = tuple(''.join(choice(ascii_letters) for i in xrange(length)) for j in xrange(cycle)) start = time() md5hex = tuple(md5(s).hexdigest() for s in data) print >> stderr, time_fmt % ('md5hex', (time() - start) * 1000) start = time() crc32x4 = tuple(''.join('%08x' % abs(crc32(s[i::4])) for i in (0, 1, 2, 3)) for s in data) print >> stderr, time_fmt % ('crc32x4', (time() - start) * 1000) start = time() startend = tuple(s[:16]+s[-16:] for s in data) print >> stderr, time_fmt % ('headtail', (time() - start) * 1000) start = time() skip = tuple(s[::(len(s)/32+1)] for s in data) print >> stderr, time_fmt % ('skipover', (time() - start) * 1000) for s in izip(data, md5hex, crc32x4, startend, skip): print join(s)
実行結果
% python hashbench.py 0 > hash0.txt string length: 0x100, cycle: 0x10000 md5hex: 199 ms crc32x4: 1081 ms headtail: 30 ms skipover: 41 ms % python hashbench.py 2 > hash1.txt string length: 0x400, cycle: 0x4000 md5hex: 83 ms crc32x4: 363 ms headtail: 10 ms skipover: 20 ms % python hashbench.py 4 > hash2.txt string length: 0x1000, cycle: 0x1000 md5hex: 52 ms crc32x4: 170 ms headtail: 2 ms skipover: 5 ms
いまさらだがFizzBuzz。
1から100まで、3の倍数5の倍数云々って、全部定数の計算じゃね?
というところに気付き、自称メタプログラマー(略してメタグラマー)俺の血が騒いだ。
定数計算なら、それは実行時ではなくコンパイル時に行なわれるべきだ……。
#include <iostream> const int FIZZ_NUM = 3; const int BUZZ_NUM = 5; const int BEGIN_NUM = 1; const int END_NUM = 101; template<int N> struct Fizz { enum {PRINT = 0, NEXT = N + 1}; static void print() {} }; template<int N> struct Buzz { enum {PRINT = 0, NEXT = N + 1}; static void print() {} }; template<int N, bool ForB> struct Number {static void print() {std::cout << N;}}; template<> struct Fizz<FIZZ_NUM> { enum {PRINT = 1, NEXT = 1}; static void print() {std::cout << "Fizz";} }; template<> struct Buzz<BUZZ_NUM> { enum {PRINT = 1, NEXT = 1}; static void print() {std::cout << "Buzz";} }; template<int N> struct Number<N, true> {static void print() {}}; template<int N, int F, int B> struct FizzBuzz { static void print() { typedef ::Fizz<F> Fizz; typedef ::Buzz<B> Buzz; Fizz::print(); Buzz::print(); Number<N, Fizz::PRINT || Buzz::PRINT>::print(); std::cout << std::endl; FizzBuzz<N + 1, Fizz::NEXT, Buzz::NEXT>::print(); } }; template<int F, int B> struct FizzBuzz<END_NUM, F, B> {static void print() {}}; int main(int argc, char **argv) { FizzBuzz<BEGIN_NUM, 1, 1>::print(); return 0; }
ifなし%なしループ系なし、しかも実行時オーバーヘッドなし!(多分)
ああ、久しぶりにC++を触ったけど、やっぱC++のテンプレートってダメダメだな。20世紀の遺物といわざるを得ない。
君がもし21世紀のモテ系イケメンメタグラマーなら、21世紀のプログラミング言語、D言語を使うべきだ!
驚くべきことに、D言語はコンパイル時に関数が実行でき、その結果をソースコードとして取り込める!
ただし実行できるのは簡単な関数だけだけど……。
import std.stdio; // これでFizzBuzzを全部出力するコードを作るぜ! string makeFizzBuzzCode() { string code; for(int i = 1; i <= 100; ++i) { // 効率? コンパイル時にそんな配慮は要らん! if(i % 3 == 0 && i % 5 == 0) { code ~= "writefln(\"FizzBuzz\");\n"; } else if(i % 3 == 0) { code ~= "writefln(\"Fizz\");\n"; } else if(i % 5 == 0) { code ~= "writefln(\"Buzz\");\n"; } else { code ~= "writefln(" ~ static_itoa(i) ~ ");\n"; } } return code; } int main(string[] args) { // おまけで生成されたコードも見せるよ。 pragma(msg, makeFizzBuzzCode()); // 生成したコードを埋め込む。コピペみたいな感覚。 mixin(makeFizzBuzzCode); return 0; } // 以下ユーティリティ。このぐらい標準で欲しいな……。 /// 整数→文字列変換(コンパイル時) string static_itoa(int n) { if(n == 0) { return "0"; } // 10で割りながら余りを文字にして追加。桁が逆転した文字列になる。 string s; for(; n; n /= 10) { s ~= ("0123456789")[n % 10]; } // 桁位置を正常にする。相変わらず効率無視。 return static_reverse(s); } /// 配列リバース(コンパイル時) /// 実行時ならarray.reverseが使えるんだけどね……。 T[] static_reverse(T)(T[] s) { T[] result; foreach_reverse(c; s) { result ~= c; } return result; } // 心配なので静的ユニットテスト(笑) unittest { static assert(static_itoa(0) == "0"); static assert(static_itoa(10) == "10"); static assert(static_itoa(999) == "999"); static assert(static_itoa(9999) == "9999"); static assert(static_itoa(12345) == "12345"); static assert(static_itoa(314159265) == "314159265"); }
コンパイル結果
$ dmd -unittest fizz_buzz.d writefln(1); writefln(2); writefln("Fizz"); writefln(4); writefln("Buzz"); writefln("Fizz"); writefln(7); writefln(8); writefln("Fizz"); writefln("Buzz"); writefln(11); writefln("Fizz"); writefln(13); writefln(14); writefln("FizzBu(ry
出力結果は略。
さすがD言語!C++やJavaやC#にできない事を平然とやってのけるッ
そこにシビれる!あこがれるゥ!
というか、
writefln(1); writefln(2); writefln("Fizz"); writefln(4);
もうwritefln(出力関数)要らなくね?
修正。
// これでFizzBuzzを全部出力するぜ! string makeFizzBuzzCode() { string code; for(int i = 1; i <= 100; ++i) { // 効率? コンパイル時にそんな配慮は要らん! if(i % 3 == 0 && i % 5 == 0) { code ~= "FizzBuzz\n"; } else if(i % 3 == 0) { code ~= "Fizz\n"; } else if(i % 5 == 0) { code ~= "Buzz\n"; } else { code ~= static_itoa(i) ~ "\n"; } } return code; } int main(string[] args) { // もうコンパイル時のメッセージしか出さない。(笑) pragma(msg, makeFizzBuzzCode()); return 0; }
コンパイル結果。
$ dmd -unittest fizz_buzz.d 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBu(ry
実行するまでもなく結果が出力された。つまり実行時間ゼロ、ということは……
世 界 最 速
みんな使おうD言語!
http://www.kmonos.net/alang/d/1.0/index.html(1.0。こっちの方が安定してる?)
実行してみたら出力に変化がなかった。アルェー?
# tree -pugs | perl -e '@line=<>; $max=(sort {$b<=>$a} map {/^(.*?)\[/; length($1)} @line)[0]; map {s/^(.*?)\[/$1 . " "x($max-length($1))."\["/e} @line; print @line'
毎回正規表現考えるのも面倒かなーとかとか。
理想を語ると出力形式指定できれば最強だなーとか妄想してた。
この辺は、ファイルにして ~/bin に放りこんで、自分好みに育て上げる、ってのがエロゲ^H^H^Hギークの楽しみ方かと。
雛型的には↓かなぁ。どうだろ。弾・monger・コーガイ氏が登場したら……滅多切りさるかもw
#!/usr/bin/perl use strict; use warnings; use Getopt::Std; use vars qw($opt_t); # オプション処理 getopts('t'); # $opt_tがセットされていたらタブ処理、ということにする。 # コマンド起動 # 引数処理とかシグナルとか面倒なところは…… open TREE, "tree -pugs ".join(" ",@ARGV,"|") or die; my @line = <TREE>; # 富豪的にいく close TREE; # ここで子プロセスの処理だっけ? # それともwaitするんだっけ? # ツリー表示部分の最大長を求める。 my $max=(sort {$b<=>$a} map {/^(.*?)\[/; length($1)} @line)[0]; # 色々やる時はユーザ名とかグループ名とかファイル名とかの最大長がいるかも foreach (@line) { if ($opt_t) { # タブ(\t)で位置をそろえるとか…… } else { s/^(.*?)\[/$1 . " "x($max-length($1))."\["/e; } print; }
treeへのオプションの与え方とか、それによる出力の変化とか考えると、結構面倒だけど、自分用に決め打ちしとけば何とかなるでしょう。
あと、「[%p<>%u<>%g<>%s]」みたいなのはCPANに転がってたりしそうな気もするので、それを使うとか。
そんなところでなかろうか。
[追記]
http://search.cpan.org/~darren/String-Format-1.14/Format.pm というのがあった。