LL Golf Hole 1 - tinyurl.comを使ってURLを短縮する
Posted feedbacks - Flatten
Nested HiddenRSSでは配信されてないみたいですけどこれもお題ですかね?
なんか、1-linerで済んじゃったんですけど...
そういうことじゃないのかなぁ...
perl -MLWP::Simple -E 'say get(q{http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo})'
回答例が異様に長くてすみません〜。趣旨のご理解ありがとうございます。
まさにそういう感じのコードを待ってました!ありがとうございます!
TinyURL APIとな!?
see: open-uri - Rubyリファレンスマニュアル
1 | ruby -ropen-uri -e "puts open('http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo').read"
|
Lisp 系は Golf 向きじゃないかなあ
1 2 3 4 5 6 7 8 9 10 11 | (use rfc.http)
(print
(cond
((#/http:\/\/tinyurl.com\/[a-z0-9-]+/
(values-ref
(http-get "tinyurl.com"
"create.php?url=http://ll.jus.or.jp/2008/info/xgihyo")
2))
=> (cut <> 0))
(else #f)))
|
HTTPを使用しました。golfっていう感じじゃないけど。 $ runhaskell TinyURL.hs http://tinyurl.com/5mngx8
see: HTTP(Hackage DB)
1 2 3 4 5 6 7 8 9 10 11 12 13 | module Main where
import Control.Arrow
import Data.Maybe
import Network.HTTP
import Network.URI
main = f "http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo"
f = runKleisli $ arr parseURI >>> arr fromJust >>> arr request
>>> Kleisli simpleHTTP >>> arr (either show rspBody) >>> Kleisli putStrLn
request uri = Request {rqURI = uri, rqMethod = GET, rqHeaders = [], rqBody = ""}
|
もっと短くなりました。 :D perl -MLWP::Simple -E 'say get "http://easyurl.jp/edz"'
see: EasyURL
ライブラリが組み込まれたコアを利用する必要があります。
SBCLで書いていますが、他の処理系でも同じような感じになると思います。
1 | sbcl --noinform --core your.core --eval '(progn(princ(kmrcl:awhen(drakma:http-request"http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo")(when(ppcre:scan"http://tinyurl.com\/[a-z0-9-]+"kmrcl:it)kmrcl:it)))(terpri)(quit))'
|
ごめんなさいごめんなさい
1 2 | #/bin/sh
wget -qO - http://tinyurl.com/api-create.php?url=$0
|
HttpURLConnectionを用いてサンプルのRubyプログラムをできるだけ忠実にJavaに変換しました。
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 | import java.net.*;
import java.io.*;
import java.util.regex.*;
public class TinyURL {
public static final String SAMPLE_URL = "http://ll.jus.or.jp/2008/info/xgihyo";
private static final Pattern TINYURL_PAT = Pattern.compile("http://tinyurl\\.com/[a-z0-9-]+");
private static final String CONVURL = "http://tinyurl.com/create.php";
public static String tinyURL(String url, String alias) throws IOException {
URL tinyUrl = new URL(CONVURL);
HttpURLConnection uc = (HttpURLConnection) tinyUrl.openConnection();
String query = "url=" + URLEncoder.encode(url, "UTF-8");
if (alias != null)
query += "&alias=" + URLEncoder.encode(alias, "UTF-8");
byte[] ba = query.getBytes("us-ascii");
uc.setRequestMethod("POST");
uc.setDoOutput(true);
uc.setFixedLengthStreamingMode(ba.length);
uc.connect();
try {
OutputStream os = uc.getOutputStream();
os.write(ba);
BufferedReader r = new BufferedReader(new InputStreamReader(uc.getInputStream(), "iso-8859-1"));
String line;
while ((line = r.readLine()) != null) {
Matcher m = TINYURL_PAT.matcher(line);
if (m.find()) {
return m.group();
}
}
return null;
} finally {
uc.disconnect();
}
}
public static String tinyURL(String url) throws IOException {
return tinyURL(url, null);
}
public static void main(String[] args) throws IOException {
System.out.println(tinyURL(SAMPLE_URL));
}
}
|
ではpure bashで。要enable-net-redirections。
1 | (echo -ne 'GET /api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo\r\nHost: tinyurl.com\r\n\r\n';while read s;do :;done<&1;echo $s>&2)>/dev/tcp/tinyurl.com/80
|
Rだって、ワンライナーくらいできるんだからね!(趣旨が違う)
1 | R -q -e "readLines('http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo', warn=F)"
|
Squeak Smalltalk で。
1 | (HTTPSocket httpGet: 'tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo') contents
|
おおう! あれ?でも、tinyurlを二回使おうとすると変なことに。
と思いつつ、http's':// の https://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2 008/info/xgihyo を圧縮した http://tinyurl.com/6hyq2m でアクセスしてみたら・・・キター(笑
なくても動くけど・・・。
どれだけ圧縮できるサービスを利用するかって話に帰着しちゃうのかな
1 | curl url.ms/qJI
|
readしなくても*で展開する方法もあります
1 | ruby -ropen-uri -e'puts *open("http://url.ms/qJI")'
|
1 2 3 4 5 6 7 8 9 | private import std.stdio, std.string, std.socket, std.socketstream;
void main() {
auto s = new SocketStream(new TcpSocket(new InternetAddress("tinyurl.com", 80)));
scope(exit) s.close;
s.writeString("GET /api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo HTTP/1.1\r\nHost: tinyurl.com\r\n\r\n");
foreach(char[] line; s) if(line.startsWith("http://")) writeln(line);
}
|
1バイトだけ短く。
1 | ruby -rnet/http -e "puts Net::HTTP.get('tinyurl.com','api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo')"
|
こういうことですか?
1 2 | "http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo"からHTTPデータ取得
それを"http:\/\/tinyurl.com\/[a-z0-9-]+"で正規表現マッチして表示
|
2行だけど ><
実行結果
------------------------
http://tinyurl.com/5mngx8
1 2 | url = new URL("http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo")
println url.getText()
|
ネット上で、この手の問題を解くためのプログラム集を見つけたので、それを活用して解いています。
Gauche での one-liner となっており、トータルで 163byte です。どう書く?org の問題だったら大抵のものは 163byte 前後で解けると思います。
1 | gosh -ugauche.process -urfc.http -E'with-output-to-process"gosh"(cut print(values-ref(http-get"ja.doukaku.org""/comment/6838/download")2)):output"/dev/tty"' -Eexit
|
1 | groovy -e "print new URL('http://url.ms/qJI').text"
|
実行はしないでください。
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 | #!/usr/bin/env ruby
require 'rubygems'
require 'mechanize'
$a = ('0'..'9').to_a + ('a'..'z').to_a
def num2str(n)
s = ""
while (n > 0)
n,r = n.divmod 36
s << $a[r]
end
return s.empty? ? "0": s
end
m = WWW::Mechanize.new
s = ""
#n = 539933837
n = 0
loop {
begin
s = "http://tinyurl.com/" + num2str(n)
res = m.get(s)
break if (res.uri.to_s == "http://ll.jus.or.jp/2008/info/xgihyo")
rescue
end
n += 1
}
puts s
|
PHPがなかったので登録して書いてみます。第二問も出るのかな?
1 | <?=join(file('http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo'));
|
1 | Console.setIn(new java.net.URL("http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo").openStream);print(readLine)
|
こそこそ・・・
1 2 3 | #! /usr/bin/env ruby
require 'open-uri'
puts *open('http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo')
|
この仕組みは面白いですね :-)
Rubyでも書いてみました。
see: #6891
1 | ruby -ropen-uri -e'eval open("http://ja.doukaku.org/comment/6891/download").read'
|
1 | ruby -ropen-uri -e'eval open("http://tinyurl.com/5kzlfb").read'
|
see: WWW::Shorten::TinyURL - Perl interface to tinyurl.com
1 | perl -MWWW::Shorten::TinyURL -e 'print makeashorterlink("http://ll.jus.or.jp/2008/info/xgihyo")'
|
see: WWW::Shorten::TinyURL - Perl interface to tinyurl.com
1 | perl -MWWW::Shorten::TinyURL -e 'print makeashorterlink "http://ll.jus.or.jp/2008/info/xgihyo"'
|
#6827 の前に考えてたものを出し忘れていました。 しかしやはりXSLTはGolfに向かない。
1 2 3 | <html x:version="2.0" xmlns:x="http://www.w3.org/1999/XSL/Transform">
<x:value-of select="unparsed-text('http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo')"/>
</html>
|
1 2 3 4 5 | import Network
import IO
main=do h<-connectTo"tinyurl.com"(PortNumber 80);hPutStr h"GET /api-create.php?u
rl=http://ll.jus.or.jp/2008/info/xgihyo HTTP/1.0\r\nHost: tinyurl.com\r\n\r\n";h
Flush h;hGetContents h>>=putStr.last.lines
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using System;
using System.Net;
using System.Text.RegularExpressions;
class Program
{
static void Main(string[] args)
{
string url = "http://tinyurl.com/create.php?url=" + args[0];
WebClient wc = new WebClient();
string r = wc.DownloadString(url);
MatchCollection mc = Regex.Matches(r, "<blockquote><b>([^<]+)</b>");
Console.WriteLine(mc[1].Groups[1].Value);
}
}
|
1 2 3 4 5 6 7 | from urllib2 import urlopen
from lxml.html import parse, submit_form
form = parse(urlopen('http://tinyurl.com/')).getroot().forms[1]
form.fields['url'] = 'http://ll.jus.or.jp/2008/info/xgihyo'
root = parse(submit_form(form)).getroot()
print root.xpath('//blockquote/b')[1].text
|
Rhinoで。そのまんますぎる。
1 | readUrl("http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo")
|
see: ClientForm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import re
from urllib2 import urlopen
from ClientForm import ParseResponse
from htmllib import HTMLParser
from formatter import NullFormatter
response = urlopen('http://tinyurl.com/')
form = ParseResponse(response, False)[1]
form['url'] = 'http://ll.jus.or.jp/2008/info/xgihyo'
h = HTMLParser(NullFormatter())
h.feed(urlopen(form.click()).read())
h.close
r = re.compile(r'http://tinyurl.com/\w+')
for i in h.anchorlist:
if r.match(i):
print i
|
1 | goruby -ropen-uri -e'pr *op("http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo")'
|
Cで書きたい。でも、どっちかというとこれはbash ワンライナー?
1 | echo "main(){printf(\"`curl 'http.php?url=http://ll.jus.or.jp/2008/info/xgihyo'`\");}" | (gcc -xc -;./a.out)
|
Scalaはscalaパッケージから相対的に名前空間にアクセスできるのでscala.io.Sourceではなくてio.Sourceでも問題ない。
なおSourceはソースファイルを読み込むためのクラスであるため本来の使い方じゃないし、文字エンコードもutf-8をデフォルトにしているので、アレではある。
scala h1.scala で実行。
1 | for(c<-io.Source.fromURL("http://tinyurl.com/api-create.php?url=http://ll.jus.or.jp/2008/info/xgihyo")) print(c)
|
GETですけどAPIを使わずにTinyURLを取得して、Regexで抜き出してます。
scala h13.scala で動かします。
1 2 3 4 5 | import io._
val url="http://ll.jus.or.jp/2008/info/xgihyo"
val t=new StringBuilder;for(c<-Source.fromURL("http://tinyurl.com/create.php?url="+url))t.append(c);
val r="""(?is).*characters:\s+<blockquote><b>([^\s]*)</b><br>.*</blockquote>.*""".r
t.toString match{case r(tu)=>println(tu) case _ =>}
|
普通に書いてみた
1 | require'open-uri';puts open('http://tinyurl.com/create.php?url=http://ll.jus.or.jp/2008/info/xgihyo',&:read)[%r|http://tinyurl.com/\w+|]
|
parseに直接urlを渡すように修正。
1 2 3 4 5 6 7 8 9 10 11 | --- a/lxml.py Tue Sep 02 15:50:19 2008 +0900
+++ b/lxml.py Tue Sep 02 15:57:27 2008 +0900
@@ -1,7 +1,6 @@
-from urllib2 import urlopen
from lxml.html import parse, submit_form
-form = parse(urlopen('http://tinyurl.com/')).getroot().forms[1]
+form = parse('http://tinyurl.com/').getroot().forms[1]
form.fields['url'] = 'http://ll.jus.or.jp/2008/info/xgihyo'
root = parse(submit_form(form)).getroot()
print root.xpath('//blockquote/b')[1].text
|
MSXMLのXmlHttpRequestを使いました。というわけでWindows限定です。さらに、#importを使っているので、Visual C++などでしかコンパイルできないです。なお、#import内のmsxml6.dllはmsxml3.dllやmsxml4.dllに置き換えても動くでしょう。
このプログラム自体は、std::wstringを全く使わなくても出来上がりますが、コピペして使い回すときの便を(少しだけ)考えてstd::wstringで入出力するようにしてあります。
XMLHTTPRequestの各メソッド・プロパティも_com_errorを投げる可能性があります。使い回すときには考慮しておいたほうが良いでしょう。
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 | #include <iostream>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/range.hpp>
#include <comdef.h>
#include <comutil.h>
#import <msxml6.dll>
_bstr_t ToBStr(const std::wstring& s)
{
return _bstr_t(SysAllocStringLen(s.c_str(), s.size()), false);
}
std::wstring ToWString(const _bstr_t& s)
{
return std::wstring(static_cast<PCWSTR>(s), static_cast<PCWSTR>(s) + s.length());
}
boost::iterator_range<const wchar_t*> BStrRange(const _bstr_t& s)
{
return boost::make_iterator_range(static_cast<PCWSTR>(s), static_cast<PCWSTR>(s) + s.length());
}
std::wstring GetTinyUrlString(const std::wstring& url)
{
MSXML2::IXMLHTTPRequestPtr xmlhttp;
HRESULT hr = xmlhttp.CreateInstance("Msxml2.XMLHTTP");
if (FAILED(hr))
{
throw _com_error(hr);
}
xmlhttp->open(L"GET", ToBStr(L"http://tinyurl.com/api-create.php?url=" + url));
xmlhttp->send();
_bstr_t result = xmlhttp->GetresponseText();
if (boost::algorithm::iequals(BStrRange(result), L"error"))
{
throw std::runtime_error("Tinyurl returns error");
}
return ToWString(result);
}
int main()
{
HRESULT hr = CoInitialize(0);
if (FAILED(hr))
{
throw _com_error(hr);
}
std::wcout << GetTinyUrlString(L"http://ll.jus.or.jp/2008/info/xgihyo") << std::endl;
CoUninitialize();
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function GetTinyUrlString(url)
{
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("GET", "http://tinyurl.com/api-create.php?url=" + url);
xmlhttp.send();
var result = xmlhttp.responseText;
if (result.toLowerCase() == "error")
{
throw "Tinyurl returns error";
}
return result;
}
WScript.Echo(GetTinyUrlString("http://ll.jus.or.jp/2008/info/xgihyo"))
|
VBScript版です。 JavaScript版の単純移植です。
1 2 3 4 5 6 7 8 9 10 11 | Function GetTinyUrlString(url)
Set xmlhttp = CreateObject("Msxml2.XMLHTTP")
xmlhttp.Open "GET", "http://tinyurl.com/api-create.php?url=" + url, False
xmlhttp.Send
result = xmlhttp.ResponseText
If LCase(result) <> "error" Then
GetTinyUrlString = result
End If
End Function
WScript.Echo(GetTinyUrlString("http://ll.jus.or.jp/2008/info/xgihyo"))
|






takano32
#6771()
[
Ruby
]
Rating-4/16=-0.25
tinyurl.com( http://tinyurl.com/ )のサービスを利用し、 http://ll.jus.or.jp/2008/info/xgihyo というURLを短縮しなさい。tinyurl.comのalias機能は使わないものとする。 なお、参考までに短縮したURLは http://tinyurl.com/5mngx8 となる。
余力のあるものはこのプログラムを短くしてみたり、短くしてみたり、短くしてみよ。
※LL Future実行委員の高野光弘です。この出題は LL Future公式の出題であり、優れたものについてはLL Golfのセッションでご紹介させていただくかもしれません。ご理解の上、ご投稿ください。また、LL Futureのチケットは現在も発売中です。よろしければ、メインイベントの方にもぜひご参加ください。
see: tinyurl.comでURLを短縮するRubyスクリプト
Rating-4/16=-0.25-0+
[ reply ]