Implémenter un raccourcisseur d'URL


12

Les URL deviennent trop longues. Vous devez donc implémenter un algorithme pour raccourcir une URL.

je. La structure d'une URL

Une URL se compose de 2 parties principales: un domaine et un chemin . Un domaine est la partie de l'URL avant la première barre oblique. Vous pouvez supposer que l'URL n'inclut pas de protocole. Le chemin est tout le reste.

ii. Le domaine

Le domaine d'une URL sera quelque chose comme: xkcd.com meta.codegolf.stackexcchhannnge.cooom. Chaque partie est séparée par des périodes, par exemple dans blag.xkcd.com, les parties sont "blag", "xkcd" et "com". Voici ce que vous en ferez:

  • S'il contient plus de deux parties, mettez les deux dernières de côté et concaténez la première lettre du reste des parties.

  • Ensuite, concaténez cela à la première lettre de l'avant-dernière partie.

  • Ajoutez un point et les deuxième et troisième lettres de l'avant-dernière partie.

  • Jetez la dernière partie.

iii. Le chemin

Le chemin sera comme: /questions/2140/ /1407/. Comme auparavant, les "pièces" sont séparées par des barres obliques. Pour chaque partie du chemin, faites:

  • Ajouter une barre oblique

  • S'il est entièrement composé de chiffres de base dix, interprétez-le comme un nombre et convertissez-le en un entier de base 36.

  • Sinon, ajoutez la première lettre de la pièce.

À la fin, ajoutez une barre oblique.

iv. Divers

  • C'est le , donc le code le plus court l'emporte.
  • Le chemin peut être vide, mais l'URL se terminera toujours par une barre oblique.
  • Il n'y aura pas de protocole (par exemple http://, file:///)
  • Il n'y aura jamais moins de deux parties dans le domaine.
  • Des échappatoires standard s'appliquent.

Exemples

Entrée: xkcd.com/72/
Sortie:x.kc/20/

Entrée: math.stackexchange.com/a/2231/
Sortie:ms.ta/a/1pz/

Entrée: hello.org/somecoolcodeintrepreteriijjkk?code=3g3fzsdg32,g2/
Sortie:h.el/s/


Dans votre dernier exemple, le chemin ne se termine-t-il pas à kket tout ce qui commence par ?est une chaîne de requête, qui ne devrait pas se terminer par une barre oblique? De plus, toutes les URL ne se terminent pas par une barre oblique /, comme www.something.com/path. Ou cela n'est-il pas pertinent aux fins de ce défi?
insertusernamehere

Ce n'est pas pertinent.
ev3commander

Réponses:


0

Pyth, 93 85 octets

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

Compilé manuellement en pseudocode pythonique:

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

Enfin, les atrocités se terminent ...


4

JavaScript (ES6), 149 octets

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

Explication

J'ai rendu cela indépendant de la solution de @ Neil mais cela a fini par ressembler beaucoup .

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

Tester


1

JavaScript ES6, 157 octets

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

Edit: 4 octets enregistrés grâce à Doᴡɴɢᴏᴀᴛ.


Vous devriez être capable de créer .split('/')et de créer .split('.')des modèles de chaînes
Downgoat

@ Doᴡɴɢᴏᴀᴛ Bah, je m'en souviens joinaussi!
Neil

1

Python 2, 378 365 octets

Mise à jour

Golfé un peu. Les ~ 150 octets pour la fonction base36 sont ennuyeux, mais je ne peux pas m'en débarrasser tant que python n'a pas intégré cela ...

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

Ancienne version

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

Étant donné que Python n'a pas de méthode intégrée pour convertir les entiers en une chaîne de base36, j'ai pris l'implémentation de numpy et l'ai analysée. Le repos est assez simple, je vais le jouer plus après le travail. Des suggestions toujours appréciées en attendant!


0

Pyhton 2, 336 329 octets

mise à jour

fixe et plus court grâce à 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

Version de DenkerAffe avec quelques mods: gérer correctement le schéma "foo / bar? Baz", plus, pas besoin de casse négative dans la fonction de conversion 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+'/'

Il y a une erreur dans votre chaîne de recherche, et la ligne entière peut également être plus courte:r+=chr((range(48,58)+range(65,91))[a%36])
webwarrior
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.