ใช้เครื่องมือย่อ URL


12

URL ยาวเกินไป ดังนั้นคุณต้องใช้อัลกอริทึมเพื่อย่อ URL

ผม. โครงสร้างของ URL

URL ที่มี 2 ส่วนหลักคือโดเมนและเส้นทาง โดเมนเป็นส่วนหนึ่งของ URL ก่อนเครื่องหมายทับแรก คุณอาจสันนิษฐานว่า URL นั้นไม่มีโปรโตคอล เส้นทางเป็นอย่างอื่น

ii โดเมน

โดเมนของ URL xkcd.com meta.codegolf.stackexcchhannnge.cooomจะเป็นสิ่งที่ชอบ แต่ละส่วนแยกเป็นช่วงเวลาเช่นในblag.xkcd.comส่วนต่าง ๆ เป็น "blag", "xkcd" และ "com" นี่คือสิ่งที่คุณจะทำกับมัน:

  • หากมีมากกว่าสองส่วนให้แยกสองส่วนสุดท้ายและต่อตัวอักษรตัวแรกของส่วนที่เหลือให้ต่อกัน

  • จากนั้นต่อให้แนบอักษรตัวแรกไปยังส่วนที่สองถึงครั้งสุดท้าย

  • เพิ่มจุดและตัวอักษรที่สองและสามของส่วนที่สองถึงครั้งสุดท้าย

  • ละทิ้งส่วนสุดท้าย

สาม. เส้นทาง

เส้นทางจะเป็นเช่น: /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และทุกสิ่งที่ขึ้นต้นด้วย?สตริงข้อความค้นหาซึ่งไม่ควรลงท้ายด้วยเครื่องหมายสแลช นอกจากนี้ยัง 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

รวบรวม pseonic pseudocode ด้วยมือ:

                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`/`

แก้ไข: บันทึกแล้ว 4 ไบต์ด้วยDoᴡɴɢᴏᴀᴛ


คุณควรจะสามารถสร้าง.split('/')และ.split('.')เป็นเทมเพลตสตริงได้
Downgoat

@ Doᴡɴɢᴏᴀᴛ Bah ฉันจำได้joinเช่นกัน!
Neil

1

Python 2, 378 365 Bytes

ปรับปรุง

Golfed มันลงเล็กน้อย ~ 150 Bytes สำหรับฟังก์ชั่น base36 นั้นน่ารำคาญ แต่ฉันไม่สามารถกำจัดมันได้จนกว่า python จะมี builtin สำหรับมัน ...

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 ไม่มีวิธีการแปลง ints เป็น base36-String ในตัวฉันจึงทำการติดตั้งจาก numpy และ golfed มันลง ส่วนที่เหลือค่อนข้างตรงไปตรงมาฉันจะตีกอล์ฟให้มากขึ้นหลังเลิกงาน ข้อเสนอแนะชื่นชมเสมอในระหว่างนี้!


0

Pyhton 2, 336 329 bytes

ปรับปรุง

คงที่และสั้นลงขอบคุณ 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 ที่มีตัวดัดแปลงบางตัว: จัดการรูปแบบ "foo / bar? baz" อย่างถูกต้องรวมทั้งไม่ต้องใช้ตัวพิมพ์ใหญ่ในฟังก์ชันการแปลงเบส 36

 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.