URL短縮サービスを実装する


12

URLが長すぎます。そのため、URLを短縮するアルゴリズムを実装する必要があります。

私。URLの構造

URLには、ドメインパスの 2つの主要部分があります。ドメインは、URLの最初のスラッシュの前の部分です。URLにプロトコルが含まれていないと想定できます。パスは他のすべてです。

ii。ドメイン

URLのドメインは次のようになりますxkcd.com meta.codegolf.stackexcchhannnge.cooom。各パートは、ピリオドで区切られています。たとえば、blag.xkcd.comでは、パートは「blag」、「xkcd」、および「com」です。これはあなたがそれで何をするかです:

  • 3つ以上の部分が含まれている場合は、最後の2つを脇に置き、残りの部分の最初の文字を連結します。

  • 次に、それを最初の文字と最後から2番目の部分に連結します。

  • ピリオドと、最後から2番目の部分の2番目と3番目の文字を追加します。

  • 最後の部分を破棄します。

iii。パス

パスは次のようになります/questions/2140/ /1407/。前と同様に、「パーツ」はスラッシュで区切られています。パス内の各部分について、次を実行します。

  • スラッシュを追加

  • 完全に10進数で構成されている場合は、数値として解釈し、36進数の整数に変換します。

  • それ以外の場合は、パーツの最初の文字を追加します。

最後に、スラッシュを追加します。

iv。その他

  • これはなので、最短のコードが優先されます。
  • パスは空でもかまいませんが、URLは常にスラッシュで終わります。
  • プロトコルが存在することはありません(例えばhttp://file:///
  • ドメイン内の部分が2つ未満になることはありません。
  • 標準の抜け穴が適用されます。

In:xkcd.com/72/
Out:x.kc/20/

In:math.stackexchange.com/a/2231/
Out:ms.ta/a/1pz/

In:hello.org/somecoolcodeintrepreteriijjkk?code=3g3fzsdg32,g2/
Out:h.el/s/


あなたの最後の例では、パスはで終了せず、kkすべてで始まる?クエリ文字列はスラッシュで終了するべきではありませんか?また、すべてのURLがスラッシュ/で終わるわけではありませんwww.something.com/path。または、これはこの課題の目的には無関係ですか?
ユーザー名をここに挿入します

それは無関係です。
ev3commander

回答:


0

Pyth、93 85バイト

Lsm@+jkUTGdjb36J<zxz\/KP>zhxz\/=cJ\.pss[mhd<J_2hePJ\.<tePJ2\/;=cK\/sm+?-djkUThdysd\/K

pythonic擬似コードに手動でコンパイル:

                z = input()                     # raw, unevaluated
                G = "abcdefghijklmnopqrstuvwxyz"
                k = ""
                T = 10
L               def y(b):                       # define y as base10to36
 sm                 join(map(lambda d:
  @+jkUTGd            (join(range(T),interleave=k)+G)[d],
                                                # the join(..)+G makes "0...9a...z"
  jb36                 convert(b,36)            # returns a list of digit values in base10
J<zxz\/         J = z[:z.index("\/")]           # domain portion
KP>zhxz\/       K = z[1+z.index("\/"):][:-1]    # path portion
=cJ\.           J = J.split(".")                # splits domain into parts
pss[            no_newline_print(join(join[     # 1 join yields a list, the other a string
 mhd<J_2            map(lambda d:d[0],J[:-2]),
 hePJ               J[:-1][-1][1],
 \.                 ".",
 <tePJ2             J[:-1][-1][1:][:2],
 \/                 "\/"
;               ])
=cK\/           K = K.split("\/")
sm              print(join(map(lambda d:
 +?-djkUThdysd\/    "\/"+(d[0] if filterOut(d,join(range(T),interleave=k)) else y(int(d))),
                    # the filter will turn pure number into empty string, which is False
 K                  K)))

最後に、耐え難いは終わります...


4

JavaScript(ES6)、149バイト

u=>u.split`/`.map((p,i)=>i?/^\d+$/.test(p)?(+p).toString(36):p[0]:(d=p.split`.`).slice(0,-1).map((s,j)=>s[l=j,0]).join``+"."+d[l].slice(1,3)).join`/`

説明

これを@Neilのソリューションから独立させましたが、最終的には非常によく似ています。

u=>
  u.split`/`.map((p,i)=>       // for each part p at index i
    i?                         // if this is not the first part
      /^\d+$/.test(p)?         // if p is only digits
        (+p).toString(36)      // return p as a base-36 number
      :p[0]                    // else return the first letter
    :
      (d=p.split`.`)           // d = domain parts
      .slice(0,-1).map((s,j)=> // for each domain part before the last
        s[l=j,0]               // return the first letter, l = index of last domain part
      ).join``
      +"."+d[l].slice(1,3)     // add the 2 letters as the final domain
  )
  .join`/`                     // output each new part separated by a slash

テスト


1

JavaScript ES6、157バイト

u=>u.split`/`.map((p,i)=>i?/^\d+$/.test(p)?(+p).toString(36):p[0]:p.split`.`.reverse().map((h,i)=>i--?i?h[0]:h[0]+'.'+h[1]+h[2]:'').reverse().join``).join`/`

編集:Doᴡɴɢᴏᴀᴛのおかげで4バイトを保存しました。


文字列テンプレートを作成.split('/')および作成できるはずです.split('.')
-Downgoat

@DoᴡɴɢᴏᴀᴛBah、私も思い出しましjoinた!
ニール

1

Python 2、378 365バイト

更新

それを少しゴルフで打ち落とした。base36関数の〜150バイトは迷惑ですが、Pythonにそのためのビルトインがあるまで、私はそれを取り除くことができません...

def b(n):
 a=abs(n);r=[];
 while a :
    r.append('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'[a%36]);a//=36
 if n<0:r.append('-')
 return''.join(reversed(r or'0'))
u=raw_input();P=u.split("/")[0].split(".")
print"".join([p[0] for p in P[0:-2]]+[P[-2][0]]+["."]+list(P[-2])[1:3]+["/"]+[b(int(p))+"/"if p.isdigit()else p[0]+"/" for p in u.split(".")[-1].split("/")[1:-1]])

古いバージョン

def b(n):
 a=abs(n)
 r=[]
 while a:
    r.append('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'[a%36])
    a//=36
 if n<0:r.append('-')
 return''.join(reversed(r or'0'))
u=raw_input()
P=u.split("/")[0].split(".")
s=""
if len(P)>2:
 for p in P[:-2]:s+=p[0]
s+=P[-2][0]+"."+P[0][1:3]
P=u.split(".")[-1].split("/")[1:-1]
for p in P:
 s+="/"+(b(int(p)) if p.isdigit() else p[0])
print s+"/"

Pythonにはintをbase36-Stringに変換するための組み込みの方法がないため、numpyから実装を取り、それを徹底的に調べました。休憩はとても簡単です。仕事の後、もっとゴルフをします。提案は常にその間に感謝します!


0

パイトン2 336の 329バイト

更新

webwarriorのおかげで修正され短くなりました

def b(a):
 r=''
 while a:
  r+=chr((range(48,58)+range(65,91))[a%36])
  a//=36
 return ''.join(reversed(r or '0'))
u=raw_input()
P=u.split('/')[0].split('.')
s=''
if len(P)>2:
 for p in P[:-2]: s+=p[0]
s+=P[-2][0]+'.'+P[0][1:3]
P=u.split('.')[-1].split('/')[1:]
for p in P: s+='/'+(b(int(p)) if p.isdigit() else p[0])
print s+'/'

元の

いくつかのmodを備えたDenkerAffeのバージョン: "foo / bar?baz"スキームを正しく処理し、さらにbase36変換関数で負のケースを必要としません。

 def b(a):
 r=''
 while a:
  r+=('0123456789ABCDEFGHUKLMNOPQRSTUVWXYZ'[a%36])
  a//=36
 return ''.join(reversed(r or '0'))
u=raw_input()
P=u.split('/')[0].split('.')
s=''
if len(P)>2:
 for p in P[:-2]: s+=p[0]
s+=P[-2][0]+'.'+P[0][1:3]
P=u.split('.')[-1].split('/')[1:]
for p in P: s+='/'+(b(int(p)) if p.isdigit() else p[0])
print s+'/'

ルックアップ文字列にエラーがあり、行全体を短くすることもできますr+=chr((range(48,58)+range(65,91))[a%36])
。– webwarrior
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.