实施网址缩短器


12

网址太长。因此,您必须实现一种缩短URL的算法。

一世。URL的结构

URL有两个主要部分:路径。域是第一个斜杠之前的URL的一部分。您可以假定URL不包含协议。道路就是一切。

ii。领域

URL的域将类似于:xkcd.com meta.codegolf.stackexcchhannnge.cooom。每个部分都是按周期分隔的,例如在中blag.xkcd.com,这些部分是“ blag”,“ xkcd”和“ com”。这是您将要执行的操作:

  • 如果它包含两个以上的部分,则将最后两部分放在一边,并连接其余部分的第一个字母。

  • 然后,将其连接到第一个字母到倒数第二个字母。

  • 添加句号以及倒数第二部分的第二个和第三个字母。

  • 丢弃最后一部分。

iii。路径

路径将类似于:/questions/2140/ /1407/。和以前一样,“部分”由斜杠分隔。对于路径中的每个部分,请执行以下操作:

  • 加上斜线

  • 如果它完全由十进制数字组成,则将其解释为数字并转换为36进制整数。

  • 否则,添加零件的第一个字母。

最后,添加一个斜线。

iv。杂项

  • 这是,因此最短的代码获胜。
  • 路径可以为空,但URL始终以斜杠结尾。
  • 不会有一个协议(例如http://file:///
  • 域中永远不会少于两个部分。
  • 有标准漏洞。

例子

进:xkcd.com/72/
出:x.kc/20/

进:math.stackexchange.com/a/2231/
出:ms.ta/a/1pz/

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


在您的最后一个示例中,路径是否不以结尾结尾,kk并且所有以开头?的查询字符串都不应该以斜杠结尾?同样,并非所有网址都以斜杠结尾/,例如www.something.com/path。还是与这项挑战的目的无关?
此处插入用户名,2016年

那是无关紧要的。
ev3commander's

Answers:


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,378365字节

更新资料

打了一下。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

Pyhton 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+'/'

原版的

DenkerAffe的版本带有一些mods:可以正确处理“ 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])
webwarrior16年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.