¿Puede Pac-Man comer esta cuerda?


46

En la versión arcade del juego, Pac-Man come pac-dots. Sin embargo, en este desafío, tiene hambre de caracteres alfanuméricos y puntuación en una cadena.

Su tarea es crear una función que alimente a Pac-Man con una cadena, evalúe si puede comerla o no, y devuelve la cadena con la ubicación de Pac-Man en ella.

Pac-Man ( <) come personajes de izquierda a derecha, dejando un guión bajo o espacio para cada personaje a medida que avanza, y su objetivo es pasar de la primera posición-1 a la última posición + 1:

1. <Pac
2. _<ac
3. __<c
4. ___<

Sin embargo, el enemigo natural de Pac-Man, el fantasma, lo detendrá si encuentra una de las letras de la palabra "FANTASMA" (no distingue entre mayúsculas y minúsculas). Su función debe devolver la cadena con la ubicación de Pac-Man cuando se encuentra con el ghostpersonaje:

1. <No!
2. _<o!

Lo único que puede derrotar a un fantasma es un perdigón de poder. Si Pac-Man llega a una letra en la palabra "PELLET" (que tampoco distingue entre mayúsculas y minúsculas) antes de llegar a un fantasma, se comerá al fantasma y seguirá moviéndose, y esa pastilla se agotará. Los pellets de poder pueden acumularse (es decir, en ppggambos fantasmas se comerían). El carácter T existe tanto como un fantasma como una bolita, por lo que puede ignorarse (tratarse como cualquier otra letra, como a).

1. <Pop
2. _<op
3. __<p
4. ___<

Para aclarar aún más, en la cadena "Pac-Man pierde aquí", se producen las siguientes operaciones:

P <P, +1 Pellet (1 pellet)
a <a
c <c
- <-
M <M
a <a
n <n
  <[space]
l <l, +1 Pellet (2 pellets)
o <o, -1 Pellet (1 pellet)
s <s, -1 Pellet (0 pellets)
e <e, +1 Pellet (1 pellet)
s <s, -1 Pellet (0 pellets)
  <[space]
h <h, ghost wins, returns
e
r
e

Ejemplos

Input: Pacman wins!
Output: ____________<

Input: Pacman loses wah-wah :(
Output: _______________<h-wah :(

Input: PELLET PELLET GHOST
Output: ___________________<

Input: Hello World!
Output: <Hello World!

Input: <_!@12<_<_<
Output: ___________<

Este es el código de golf: gana la puntuación más baja en bytes.


29
¿Entonces los pellets no tienen fecha de vencimiento?
Rɪᴋᴇʀ

¿Se aceptan tabulaciones finales en la salida?
Katenkyo

77
+1 por el hecho de que "aquí" es donde pacman pierde. Caso de prueba inteligente.
Olivier Dulac

55
> [I] n este desafío, tiene hambre de caracteres alfanuméricos y puntuación en una cadena. ... Yacc- hombre?
Kaz

99
Ahora veo un pacman gris camuflado con labios negros cada vez que miro el <símbolo ...
QBrute

Respuestas:


16

Jalea, 34 33 bytes

Œl“ʋʋ“ṁḍ»ċ€Ð€IF+\‘0ṭi0ð’”_×;”<;ṫ@

Pruébalo en línea!

Creo que finalmente estoy empezando a entender a Jelly. Siente un poco de miedo.


55
Empezaría a preocuparme cuando puedas leerlo con fluidez :)
quetzalcoatl

30

Retina , 55 38 bytes

i`^(([elp])|[^ghos]|(?<-2>.))*
$.&$*_<

Pruébalo en línea! (La primera línea solo permite ejecutar varios casos de prueba a la vez).

Explicación

El problema es esencialmente encontrar el prefijo más largo que no tenga un paréntesis de cierre sin igual. Salvo que podemos utilizar e, lo pen lugar de (y, o bien g, h, oo sen lugar de ).

Por lo tanto, esta solución es casi un ejemplo de libro de texto de grupos de equilibrio. No entraré en demasiados detalles sobre cómo funcionan, ya que este código es esencialmente el mismo que el ejemplo estándar que puede leer en mi respuesta SO sobre grupos de equilibrio .

Todo el programa es, por lo tanto, una única sustitución de expresiones regulares. El iactiva mayúsculas y minúsculas. Luego emparejamos un pellet con [elp]e incrementamos el contador de profundidad (en la forma de la pila de captura del grupo 2), o emparejamos algo con lo que no es un fantasma [ghos]o emparejamos un fantasma .y disminuimos el contador de profundidad haciendo estallar desde la pila 2. Por supuesto, en principio esto permite hacer coincidir una pastilla con la [^ghos]sección o un no fantasma con la .sección, pero gracias a la coincidencia codiciosa y la forma en que se remonta la expresión regular, el motor de expresiones regulares nunca intenta estas posibilidades.

La sustitución luego usa dos características específicas de Retina: $*repite el personaje a su derecha tantas veces como lo especifique el token a su izquierda. Esa ficha es $.&la duración de todo el partido. Esto solo significa que reemplazamos cada personaje en el partido con a _. Y luego también agregamos un <a esos guiones bajos. La parte de la entrada que no se come simplemente no se ve afectada por la sustitución.


¡Buen abuso de capturar grupos!
Leaky Nun

11
@LeakyNun Abuse? Para eso están hechos los grupos de equilibrio. : D
Martin Ender

1
Hola, mira, una respuesta de Retina que se parece remotamente a la expresión regular que uso
gato

10

Python 2, 114 113 108 bytes

s=raw_input()
p=i=0
for c in s:
 p+=(c in'plePLE')-(c in'ghosGHOS')
 if p<0:break
 i+=1
print'_'*i+'<'+s[i:]

Su función regresa None, no la respuesta. ¿Y cómo cuentas 107? Cuento 110.
Stefan Pochmann

@StefanPochmann los espacios dobles son pestañas y se permite imprimir la respuesta en lugar de devolverla
Azul

@muddyfish Ah, gracias. Sin embargo, no parecen ser pestañas aquí, ni siquiera cuando voy a "editar". Y el problema dice claramente "retorno" ... ¿existen reglas para todo el sitio que lo anulen o no? (Soy bastante nuevo aquí y no lo sé)
Stefan Pochmann

Las pestañas @StefanPochmann son consumidas por SE (normalmente convertidas a 4 espacios). A menos que se indique explícitamente la impresión en una función está permitida. Sin embargo, el OP probablemente no quiso anular esto
azul el

Creo que es razonable decir que siempre debe regresar si es una función o leer desde stdin e imprimir. Cambiaré a lectura desde stdin, que de todos modos debería ser más corto.
Arfie

8

Python 2, 89 bytes

A veces, mi obstinada determinación de hacer de Python un lenguaje funcional tiene sus beneficios.

def f(s,l=1):l+=(s[:1]in'plePLE')-(s[:1]in'ghosGHOS');return s*l and'_'+f(s[1:],l)or'<'+s

(Ligeramente) sin golf:

def f(s, l=1):
    l += (s[:1] in 'plePLE') - (s[:1] in 'ghosGHOS')
    return (s * l) and ('_' + f(s[1:], l)) or ('<' + s)

Construye la cadena de resultados usando recursividad. La actualización de l(for "lives") agrega 1 para pellets ( True - False == 1), resta 1 para ghosts ( False - True == -1) y agrega 0 para cualquier otro personaje. También agrega 0 cuando ses la cadena vacía, gracias al corte de Python y al hecho de que '' in any_str == True, de modo que el pellet y el fantasma se cancelan.

La declaración de devolución se utiliza test and b or aen lugar de a if test else bguardar un byte. El caso base de recursión ocurre cuando la cuerda termina o Pac-Man se queda sin gránulos, representado sucintamente como s*p, lo que es igual ''(y por lo tanto se evalúa como falso) cuando s == ''o bien p == 0.


8

C #, 269 256 232 212 211 Bytes

Primero publica aquí, por lo que probablemente sea mucho más largo de lo que podría ser (y probablemente porque está en C #). ¡Algún consejo sobre dónde podría acortarlo sería genial!

¡Gracias a todos en los comentarios que me ayudaron!

Versión de golf

static void p(string x){int p=0,i=0;string t='<'+x;var s=t.ToCharArray();for(;++i<s.Length;){if("PELpel".Contains(s[i]))p++;if("GHOSghos".Contains(s[i])&&--p<0)break;s[i]='<';if(i>0)s[i-1]='_';}Console.Write(s);}

Versión sin golf

static void p(string x) {
 int p = 0, i = 0;
 string t = '<' + x;
 var s = t.ToCharArray();
 for (; ++i < s.Length;) {
  if ("PELpel".Contains(s[i])) p++;
  if ("GHOSghos".Contains(s[i]) && --p < 0) break;
  s[i] = '<';
  if (i > 0) s[i - 1] = '_';
 }
 Console.Write(s);
}

1
Puede reemplazar los tipos en eliminaciones variables utilizando la palabra clave var. por ejemplo var temp = '' + input; El bucle for se puede reescribir para guardar 4 caracteres: for (var i = 0; i ++ <s.Length;)
CSharpie

1
Puede usar comas para las declaraciones "int i = 0, p = 0; string P =" PELpel ", G =" GHOSghos ", t = '' + x;" y el cambio de @CSharpie, haciendo el bucle "for (; i ++ <s.Length;)". Además, puede "Console.Write (s);" directamente para un total de 235 bytes.
Nickson

1
Creo que también debería funcionar sin elseguardar 5 caracteres más. Y al iniciar el ciclo en i = 1, debería poder eliminar el último si, ya que el código se puede ejecutar cada vez.
Frozn

1
Puede deshacerse de su declaración c y simplemente alinear el s[i]acceso para 5 caracteres.
JustinM - Restablece a Monica el

1
¿Vale la pena asignar P="PELpel"y G="GHOSghos"? Solo los usas una vez cada uno. ¿Me estoy perdiendo algo o son solo 4 caracteres adicionales? Además, ¿necesitas el else? "PELpel".Contains(c)y "GHOSghos".Contains(c)debe ser mutuamente excluyente.
jpmc26

7

Pyth, 53 48 44 bytes

4 bytes gracias a @ Pietu1998 por el truco !!@-> }(que solo las personas que conocen Pyth pueden entender)

++ * Jf <@ + sM._m - !! @ d "PELpel" !! @ d "GHOSghos" Q_1T00 \ _ \ <> QJ 
++ * Jf <@ + sM._m - !! @ d "PEL" !! @ d "GHOS" rQ1_1T00 \ _ \ <> QJ
++ * Jf <@ + sM._m-} d "PEL"} d "GHOS" rz1_1T00 \ _ \ <> zJ

Banco de pruebas.


17
que solo las personas que conocen Pyth pueden entender Bueno, como casi todo el resto del código, naturalmente
Luis Mendo

44
@LuisMendo Para ser justos con las personas que no conocen a Pyth, estoy bastante seguro de que la mayoría de ellos podrían entender que la intersección del conjunto entre un conjunto singleton y otro conjunto que tiene miembros es equivalente a que el miembro del conjunto singleton sea miembro del conjunto más grande: P
FryAmTheEggman

1
@FryAmTheEggman, por lo que obviamente !!@es solo un trigrafo }, ¿verdad? : p
CAD97

7

MATL , 37 36 35 bytes

tkt'ghos'mw'pel'm-Ys1=Y>&)g95*60bhh

Pruébalo en línea!

Explicación

tkt      % Input string implicitly. Duplicate, convert to lower case, duplicate
'ghos'm  % True for "ghost" characters
w'pel'm  % Swap to bring lowercase copy to top. True for "pellet" characters
-Ys      % Subtract, cumulative sum. Pac-Man can reach until the first "1"
1=       % True for entries that equal 1
Y>       % Cumulative maximum. This gives false until the first true is found, and
         % true from there on
&)       % Split original string in two parts, given by the zeros and ones respectively
g95*     % Convert the first part into ones and multiply by 95. This gives a numerical
         % array containing number 95 (ASCII for '_')
60       % Push 60 (ASCII for '<')
b        % Bubble up second part of original string
hh       % Concatenate the three strings/arrays, automatically converting to char

7

JavaScript (ES6), 98 bytes

s=>s.replace(/./g,c=>p<0?c:(p+=/[elp]/i.test(c)-/[ghos]/i.test(c))<0?"<"+c:"_",p=0)+"<".slice(p<0)

Explicación: pmantiene el número actual de pellets. Si ya es negativo, simplemente devolvemos el carácter y seguimos adelante, para que el resto de la cadena no se toque. De lo contrario, examinamos el carácter actual y, si eso se pvuelve negativo, insertamos el <carácter; de lo contrario, reemplazamos el carácter actual con _. Finalmente, si pnunca se vuelve negativo, sufijamos <a en la cadena.


4

Pyth, 47 46 44 bytes

++*\_Kh+f!h=+Z-}Jr@zT0"pel"}J"ghos"Uzlz\<>zK

Pruébalo en línea. Banco de pruebas.

Un enfoque bastante diferente al de Leaky Nun, y estoy bastante seguro de que esto se puede jugar más.


Usar en Zlugar de Gy cambiar f!af!h
Leaky Nun

@LeakyNun También lo descubrí en otra pestaña. Gracias.
PurkkaKoodari

2
Creo que el tde "ghost"debe quitar
Leaky Nun

Si seguimos jugando al golf con nuestras soluciones, ¿cuál es la diferencia que define a nuestras soluciones?
Leaky Nun

@LeakyNun No estoy seguro de cuál de estos está más cerca, pero mi primer intento me dio 43 bytes , y no creo que necesite agregar una tercera respuesta. ¿Quizás deberíamos trabajar juntos en la sala de chat de Pyth?
FryAmTheEggman

4

Lua, 198 190 184 185 163 Bytes

Ok, lo admito, esto es largo. Muy largo. Lua tiene algunas herramientas para jugar con cuerdas, pero es limitado, lo mismo ocurre con los condicionales que ocupan muchos espacios.

Editar: gracias @LeakyNun por salvarme 9 bytes :) Perdí algunos bytes para corregir un error

Edición 2: solución de 163 bytes encontrada por @LeakyNun

i=0p=0n=...for c in n:gmatch"."do
p=p+(c:find"[ghosGHOS]"and-1or c:find"[pelPEL]"and 1or 0)if p<0then
break else i=i+1 end end print(('_'):rep(i)..'<'..n:sub(i+1))

Viejo 185

p=0z=(...):gsub(".",function(c)p=p+(c:find"[ghosGHOS]"and-1or
c:find"[pelPEL]"and 1or 0)s=p<0 and 1or s
return s and c or'_'end)_,i,s=z:find"(_+)"print((s or'')..'<'..z:sub(1+(i or 0)))

Sin golf

i=0                        -- number of characters eaten
p=0                        -- pellet counter
n=...                      -- shorthand for the argument
for c in n:gmatch"."       -- iterate over each characters in the input
do
  p=p+(c:find"[ghosGHOS]"  -- if the current char is a GHOST
        and-1              -- decrement the pellet counter
      or c:find"[pelPEL]"  -- if it's a PELLET
        and 1              -- increment it
      or 0)                -- else, leave it alone
  if p<0                   -- if we try to eat a ghost without pellet
  then 
    break                  -- stop iterating
  else
    i=i+1                  -- else, increment our score
  end
end

print(('_'):rep(i)         -- print i*'_'
  ..'<'                    -- appended with Pacman
  ..n:sub(i+1))            -- appended with the remaining characters if we died

Elimine d=c:lower()y busque también los caracteres en mayúscula
Leaky Nun

and 1or s and 1or s s and s
Leaky Nun

@LeakyNun no vio que sería más corto escribir solo todas las cartas ... Gracias. Además, el segundo comentario menciona algo que cambié, pero solo en el no golfista> _ <
Katenkyo

print(('').rep('_',i)..','..z:sub(i+1))
Leaky Nun

@LeakyNun Estoy trabajando en una solución similar, pero el problema proviene del hecho de que ipuede sernil
Katenkyo

3

Python 3, 176 157 150 149 134 133 124 bytes

Defina una función llamada fque tome la cadena como argumento

def f(s):
 n=i=0
 for c in s:
  if c in"GgHhOoSs":
   if n:n-=1
   else:break
  n+=c in"PpEeLl";i+=1
 return"_"*i+"<"+s[i:]

Probablemente se pueda jugar más al golf

Gracias a todos los que comentaron: D


1
﹐ Eliminar x=c.upper()y buscar coincidencias en minúsculas
Leaky Nun

Puede guardar algunas escribiendo algunas expresiones en la misma línea separadas por una en ;lugar de tener cada una en su propia línea. También puede usar Python 2, que le permite usar espacios como primer nivel de intendación y pestañas como segundo.
Denker

n=i=0, no n=0y i=0. t[i]="_"en lugar de t[i] = "_", lo mismo para t[i] = "<". return''.join(t), quita ese espacio.
Erik el Outgolfer

@LeakyNun Hay mayúsculas en los casos de prueba.
TuxCrafting

@ TùxCräftîñg No, quieren decir "GgHhOoSs"y "PpEeLl".
Erik the Outgolfer

2

Python 3, 114 110 bytes

Mi primer código de golf.

Gracias al Dr. Green Eggs y Iron Man por guardar 4 bytes.

l,x=1,0
f,y,s="ghosGHOS","pelPEL",input()
while s[x:]*l:l+=(s[x]in y)-(s[x]in f);x+=l>0
print("_"*x+"<"+s[x:])

Utiliza la evaluación de booleanos a uno y cero para condensar un AND lógico a una multiplicación. (0 * 0 = 0, 1 * 0 = 0, 1 * 1 = 1). Espero que este sea un buen primer intento.


Buena respuesta, y bienvenido al sitio! ¿Qué versión de Python estás usando? Es posible que desee especificar eso. Además, no lo he probado, pero es posible que pueda while s[x:]*lsacar 4 bytes.
DJMcMayhem

1

Powershell, 185

{$l=1;$o="";for($i=0;($i -lt $_.Length) -or (($o+="<") -and 0); $i++){if ($_[$i] -match '[pel]'){$l++}if($_[$i] -match '[ghos]'){$l--}if(!$l){$o+="<"+$_.substring($i);break}$o+="_"}$o}

Sin golf:

("Pacman wins!",
"Pacman loses wah-wah :(",
"PELLET PELLET GHOST",
"Hello World!"
) | 
% {
    $l=1;$o="";
    for($i = 0; ($i -lt $_.Length) -or (($o+="<") -and 0); $i++) {
        if ($_[$i] -match '[pel]') { $l++ }
        if ($_[$i] -match '[ghos]') { $l--}
        if (!$l) { $o+="<"+$_.substring($i); break }        
        $o += "_"
    }
    $o
}

1

Python3, 211 184 bytes

El argumento 's' es una cadena

def f(s):
    p=c=0
    for i in s:
        if i in "gGhHoOsS":
            if p<1:break
            else:p-=1
        if i in "pPeElL":p+=1
        c+=1
    return"_"*c + "<" + s[c:]

Agradecería cualquier consejo de golf ya que este es mi primer intento de golf de código

Gracias por comentar :)


2
¡Bienvenido a Programming Puzzles & Code Golf! Algunos consejos: Hay muchos espacios en blanco innecesarios entre los operadores. Eliminarlos ahorraría una buena cantidad de bytes. También puede usar Python 2, que le permite usar espacios como primer nivel de intendación y pestañas para los otros.
Denker

1
Puede reemplazar el primero return "_"*c + "<" + s[c:]con solo un breakcódigo que se ejecutará después del ciclo for de todos modos.
Arfie

Pruébalo en línea! Obtuve 183 bytes por cierto. ¿Hay una nueva línea final que contó?
Pavel

1

Haskell 119 113 bytes

Gracias a Daniel Wagner por 6 bytes menos.

p=(0!)
n!(c:s)|elem c"ghosGHOS"=if n<1then '<':c:s else(n-1)&s|elem c"elpELP"=(n+1)&s|0<1=n&s
_!_="<"
n&s='_':n!s

Llámalo como p "Hello World!".

El 1thenes un caso de borde que se interpreta correctamente en mi GHC (7.10), pero arroja la mayoría de los resaltadores de sintaxis. Por lo tanto, podría interpretarse de manera diferente en su compilador también.

Sin golf:

pacman string = go 0 string

-- | In the golfed version: (!)
go _   []                   = "<"                            -- won
go pellets (char:string)
 | char `elem` "ghosGHOS"
 = if pellets < 1        then '<':char:string                -- lost
                         else nextStep (pellets - 1) string  -- ghost
 | char `elem` "elpELP"
 =                            nextStep (pellets + 1) string  -- pellet
 | otherwise
 =                            nextStep  pellets      string  -- anything else

-- | In the golfed version: (&)
nextStep pellets string = '_':(go pellets string)

1
Puede guardar algunos bytes poniendo todos los guardias en la misma línea, por ejemplo n!(c:s)|elem c"blah"=blah|elem c"blah"=blah|0<1=blah.
Daniel Wagner

@Daniel Wagner Buen consejo, gracias!
MarLinn

¿Puedes agregar un enlace TIO ? Sigo recibiendo errores cuando intento que funcione.
Pavel

1

C, 237 bytes

#include<stdio.h>
#include<string.h>
main(p,i,j){char s[99];fgets(s,99,stdin);for(p=i=0;s[i];++i){if(strchr("GHOSghos",s[i])){if(p)p--;else break;}else if(strchr("PELpel",s[i]))p++;}j=i-(s[i]==0);while(j--)printf("_");printf("<%s",s+i);}

1

C ++, 315 373 327 Bytes

(Nota: sigue jugando al golf)

#include <iostream>
#include <string>
using namespace std;
int main(){string input;getline(cin, input);
if(input.find("Pac-Man loses")!=string::npos||input.find("Pacman loses")!=string::npos)
    cout<<"<"<<input.substr(15,input.length()-1);
else{for(unsigned i=0;i<=input.length();++i)
    cout << "_";
cout<<"<";
}return 0;
}

1
Pac-Man no pierde cuando se supone que debe ser.
tildearrow

Hola @tildearrow, ¡gracias por revisar mi código! Actualizaré mi publicación.
tachma

Creo que esto se puede jugar más al golf. Pruebe quitando las nuevas líneas / espacios después if(), y la eliminación de los espacios alrededor !=, ||, =, -, y <=. Además, ¿no cin>>inputfunciona en lugar de getline? También puedes condensar alrededor ;.
NoOneIsHere

@NoOneIsHere, gracias por tu comentario! En realidad, soy nuevo en el código de golf, así que intentaré jugar un poco más mi código y actualizar mi publicación. Si tiene algún otro consejo útil sobre el golf de código, realmente lo agradecería.
tachma

1
Puede consultar los Consejos para el golf C / C ++ .
NoOneIsHere

1

Ruby, (119 bytes)

q=i=0;a=$**" ";a.split(//).each{|c|q+=((c+?p=~/[ple]/i)^1)-((c+?g=~/[ghos]/i)^1);q<0?break : i+=1};p ?_*i+?<+a[i..-1]

Probablemente hay algunas cosas que me estoy perdiendo, ya que soy nuevo en esto ...

Ruby es mi amiga :)


1
Bienvenido a PPCG!
FlipTack

0

Perl, 54 (52 + 2) bytes

s/([pel](?1)*[ghos]|[^ghos
])*/'_'x(length$&).'<'/ei

Debe -pespecificarse en las opciones de línea de comandos.

Explicación:

La -popción hace que la declaración se envuelva en un ciclo de lectura-modificación-impresión, donde durante cada iteración del ciclo, $_contiene una línea de entrada, incluido el delimitador de línea.

La expresión regular es en gran medida la misma idea que en la respuesta Retina.

Llame al patrón de búsqueda ([pel](?1)*[ghos]|[^ghos ])*"aceptable". Entonces se puede definir recursivamente como:

Una cadena es "aceptable" si:

  • Es un carácter en PELLETexcepto T, seguido de una cadena aceptable, seguido de un carácter en GHOSTexcepto T.
  • Es un personaje que no está, GHOSTexcepto Tque no es un personaje de nueva línea.
  • Es una concatenación de cualquier número (incluido 0) de cadenas aceptables.

Esta definición permite más pellets que fantasmas: un PELpersonaje puede ser emparejado como un personaje de pellet o un personaje no fantasma.

La cadena vacía se considera aceptable, por lo tanto, se garantiza que la expresión regular coincida en la posición 0, donde se emparejará la subcadena más larga aceptable.

Esta subcadena más larga aceptable se corresponde con guiones bajos de igual longitud, seguidos de <.


Las banderas de iirc como -p cuentan como un byte cada una.
Pavel

1
@Pavel Es complicado. Si la invocación normal sin -pya utilizada -, por ejemplo, perl -e-> perl -pe, entonces el -es libre. Pero creo que la perl -eversión es más larga debido a las citas, así que creo que no puedo usar eso aquí.
hvd
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.