Implementar un acortador de URL

12

Las URL son demasiado largas. Por lo tanto, debe implementar un algoritmo para acortar una URL.

yo. La estructura de una URL

Una URL tiene 2 partes principales: un dominio y una ruta . Un dominio es la parte de la URL antes de la primera barra inclinada. Puede suponer que la URL no incluye un protocolo. El camino es todo lo demás.

ii. El dominio

El dominio de una dirección URL será algo como: xkcd.com meta.codegolf.stackexcchhannnge.cooom. Cada parte está separada por blag.xkcd.compuntos , por ejemplo, en , las partes son "blag", "xkcd" y "com". Esto es lo que harás con él:

  • Si contiene más de dos partes, ponga las dos últimas a un lado y concatene la primera letra del resto de las partes.

  • Luego, concatena eso a la primera letra a la penúltima parte.

  • Agregue un punto y la segunda y tercera letra de la penúltima parte.

  • Desechar la última parte.

iii) El camino

El camino será como: /questions/2140/ /1407/. Como antes, las "partes" están separadas por barras. Para cada parte de la ruta, haga:

  • Agregar una barra inclinada

  • Si está completamente hecho de dígitos de base diez, interprete como un número y conviértalo a un entero de base 36.

  • De lo contrario, agregue la primera letra de la parte.

Al final, agregue una barra.

iv. Misceláneos

  • Este es el , por lo que gana el código más corto.
  • La ruta puede estar vacía, pero la URL siempre terminará con una barra inclinada.
  • No habrá un protocolo (p http://. Ej . file:///)
  • Nunca habrá menos de dos partes en el dominio.
  • Se aplican lagunas estándar.

Ejemplos

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/

ev3commander
fuente
En su último ejemplo, ¿la ruta no termina kky todo lo que comienza ?es una cadena de consulta, que no debería terminar con una barra diagonal? Además, no todas las URL terminarán con una barra inclinada /, como www.something.com/path. ¿O es esto irrelevante para el propósito de este desafío?
insertusernamehere
Eso es irrelevante.
ev3commander

Respuestas:

0

Pyth, 93 85 bytes

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

Compilado a mano a pseudocódigo pitónico:

                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)))

Finalmente, la insoportable termina ...

busukxuan
fuente
4

JavaScript (ES6), 149 bytes

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

Explicación

Lo hice independiente de la solución de @ Neil, pero terminó pareciéndose muy similar.

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

Prueba

usuario81655
fuente
1

JavaScript ES6, 157 bytes

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

Editar: Guardado 4 bytes gracias a Doᴡɴɢᴏᴀᴛ.

Neil
fuente
Debería poder crear .split('/')y crear .split('.')plantillas de cadena
Downgoat
@ Doᴡɴɢᴏᴀᴛ Bah, ¡también lo recordaba join!
Neil
1

Python 2, 378 365 Bytes

Actualizar

Golfed por un poco. Los ~ 150 Bytes para la función base36 son molestos, pero no puedo deshacerme de él hasta que Python tenga un incorporado para eso ...

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]])

Versión antigua

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+"/"

Como Python no tiene una forma integrada de convertir ints en una cadena base36, tomé la implementación de numpy y la bajé. El descanso es bastante sencillo, lo jugaré más después del trabajo. Sugerencias siempre apreciadas mientras tanto!

Denker
fuente
0

Pyhton 2, 336 329 bytes

actualizar

arreglado y más corto gracias a 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+'/'

original

La versión de DenkerAffe con algunas modificaciones: maneja correctamente el esquema "foo / bar? Baz", además, no hay necesidad de mayúsculas y minúsculas en la función de conversión 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+'/'
Setop
fuente
Hay un error en su cadena de búsqueda, y también toda la línea puede ser más corta:r+=chr((range(48,58)+range(65,91))[a%36])
webwarrior