ETAOIN SHRDLU golf


43

Descripción breve y dulce del desafío:
basado en ETAOIN SHRDLU , su desafío es escribir el programa o la función más corta en cualquier idioma que genere las 26 letras del alfabeto inglés en función de su frecuencia en la entrada.

Especificaciones realmente largas, secas y completas:

  • Su programa / función recibirá como entrada una cadena de texto, que contendrá una o más letras mayúsculas y / o minúsculas y también puede contener signos de puntuación, números, símbolos y otros caracteres no alfabéticos.
  • El programa / función debe generar solo las 26 letras MAYÚSCULAS del alfabeto inglés, incluidas las que no aparecen en la entrada, ordenadas de mayor a menor según la cantidad de veces que aparecen en la entrada.
  • Editar: la frecuencia se calcula entre mayúsculas y minúsculas, pero la salida debe estar en mayúsculas.
  • Si dos o más letras tienen la misma frecuencia, pueden estar en cualquier orden.
  • No se permite ninguna otra salida, como el espacio en blanco.
  • Editar 01/07/2014: Basado en comentarios, estoy modificando esta regla. El único otro resultado permitido es el espacio en blanco inicial y / o final opcional, como una nueva línea final. No se permite ninguna otra salida.
  • Se permite un comportamiento indefinido para la entrada que no contiene ninguna letra.

El ganador será elegido dentro de 7 días, ¡así que escribe esos dedos!


Entrada de ejemplo:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vitae erat velit. Mauris gravida euismod libero ut tincidunt. Phasellus elit dui, consectetur et egestas in, aliquam vitae diam. Donec eget varius ante. Vestibulum cursus diam aliquet, egestas orci quis, placerat dolor. Proin vel nisi lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam erat volutpat. Etiam libero tortor, ornare id dui eget, posuere dignissim libero. Pellentesque commodo consequat volutpat. Integer hendrerit sapien libero, vel viverra augue facilisis sit amet. Quisque consectetur eget nisl quis dignissim. Ut lacinia pretium quam a placerat.
Morbi sed interdum risus, nec pretium lectus. Morbi imperdiet est id accumsan molestie. Duis sed fermentum nisl. Nunc vitae augue mattis, dictum lectus vel, accumsan nisl. Sed ultricies adipiscing rhoncus. Vivamus eu lacus a enim venenatis eleifend. Praesent consectetur tortor non eleifend ultricies. Mauris et odio posuere, auctor erat at, fringilla est. Proin in vestibulum erat. Maecenas congue commodo ante vel varius. Sed tempus mi ut metus gravida, nec dictum libero dapibus. Morbi quis viverra elit. Ut pharetra neque eget lacus tincidunt dictum. Fusce scelerisque viverra tellus et pretium.
Fusce varius adipiscing odio. Nulla imperdiet faucibus sem, at rhoncus ipsum adipiscing vitae. Phasellus imperdiet congue lacus et mollis. Nullam egestas mauris magna, et mollis lectus varius ut. Sed sollicitudin adipiscing dolor, vel elementum elit laoreet molestie. Aliquam nec nulla vel sem ultrices ullamcorper. Nullam nec felis magna. Duis sodales orci non justo aliquam tempus. Integer mi diam, tempor sed vulputate et, varius et nunc. Vestibulum sodales ipsum id mi pharetra, ut convallis mi accumsan. Sed dictum volutpat vestibulum.
Quisque ac dolor sagittis, aliquam libero at, euismod enim. Nulla ullamcorper posuere nulla vitae varius. Nam at dolor non libero elementum pellentesque in in lorem. Fusce porttitor turpis in quam placerat varius. Donec lorem orci, condimentum eu sapien sit amet, aliquet commodo magna. Quisque sed lectus sit amet arcu euismod accumsan et non nunc. Phasellus placerat congue metus, feugiat posuere leo dictum quis. Sed ultricies feugiat eros dignissim bibendum.
Mauris scelerisque consectetur libero eget varius. Aenean neque nunc, ullamcorper vitae orci in, auctor ornare sapien. Nam lacinia molestie imperdiet. Nam vitae mattis nibh. Vestibulum consequat tellus ac nisi sagittis pulvinar. Nullam mollis ornare quam, et venenatis leo porttitor sit amet. Nulla urna neque, dignissim non orci ut, volutpat ultrices erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque vestibulum tellus nec eros faucibus porta.

Salida de ejemplo:

EITUSALNROMCDPVGQBFHJKWXYZ

Nota: hay un vínculo de 5 vías KWXYZpara esa entrada.

Editar:

¡La competencia ha terminado! Gracias a todos los que participaron. Y ahora para el ganador (s): las respuestas de Dennis 'CJam y de Isaac Pyth llegaron a la friolera de 19 caracteres. (Lo siento, pero no voy a aceptar ninguna de las respuestas porque creo que sería injusto para la otra). Editar: Siguiendo el consejo de Dennis, voy a marcar su respuesta como aceptada porque fue la primera en llegar a 19 caracteres. Las menciones honoríficas van a la respuesta de Golfscript en tercer lugar de Ilmari Karonen en 22 caracteres, así como a la respuesta Python de 75 char de undergroundmonorail que obtuvo la mayor cantidad de votos. Una vez más, ¡gracias a todos los que participaron!


¿Se mide la frecuencia solo para las letras mayúsculas de la entrada?
Howard

2
@IlmariKaronen sí, las nuevas líneas cuentan como espacios en blanco, por lo que no se permitiría.
Abraham

8
@Abraham: OMI; si se permite una nueva línea final (específicamente) para algunos idiomas, generalmente se debe permitir para todos los idiomas; no menos importante porque una secuencia de texto debe terminar con una nueva línea seguida de EOF.
Williham Totland

3
@WillihamTotland, según la cantidad de votos a favor que tenga su comentario, modificaré las reglas para permitir una nueva línea final.
Abraham

1
¿Qué hacer si hay dos respuestas con el código más corto? sugiere otorgar la marca de verificación verde a la solución anterior. isaacg publicó su respuesta primero, yo jugué la mía con 19 bytes primero. Cualquiera que sea el desempate que elija estará bien para mí, pero no tener una respuesta aceptada es un poco anti-climático en mi opinión.
Dennis

Respuestas:


26

CJam, 21 19 bytes

qeu:A;'[,65>{A\-,}$

Pruébalo en línea.

Ejemplo

$ cjam etaoin.cjam <<< "~XyxY YyxZ"
YXZABCDEFGHIJKLMNOPQRSTUVW

(sin nueva línea)

Cómo funciona

qeu:A; " Read from STDIN, convert to uppercase, save in the variable “A” and discard, ";
'[,    " Push an array of all ASCII characters before “[” (NUL to “Z”).               ";
65>    " Remove the first 64 characters (NUL to “@”).                                 ";
{      " Sort the array of characters by the following mapping:                       ";
  A\   " Swap the character with the string saved in variable “A”.                    ";
  -    " Remove all occurrences of the character from the string.                     ";
  ,    " Push the length of the string.                                               ";
}$     "                                                                              ";

Más ocurrencias significa que se eliminan más caracteres, por lo que los caracteres más frecuentes aparecen al comienzo del conjunto.


Muy inteligente de hecho.
Abraham

¡Felicitaciones a @Dennis por ganar el concurso!
Abraham

43

Python 2 o 3 - 77 75 bytes

f=lambda s:''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1]

Tenía una respuesta antes de que la información obtenida de STDIN, pero me di cuenta de que técnicamente no era válida. Utilicé el input()que obtiene solo una línea, pero la entrada de ejemplo de la pregunta implica que debe manejar varias líneas a la vez. Para cumplir con las especificaciones, convertí mi respuesta en una función que toma un argumento de cadena. Para mi sorpresa, ¡era dos bytes más pequeño! No se me ocurrió eso print(...)y input()fueron más largos que f=lambda s:y s.

Esto también hace que la respuesta sea compatible tanto con Python 2 como con Python 3. Originalmente, solo era Python 3, porque se usaba input()(que se llamó raw_input()en 2). Ahora que es una función, funciona en ambos.

Explicado

                                  range(65,91)                              # The numbers 65 to 90
                          map(chr,range(65,91))                             # Convert to ASCII

                                                    s                       # The input string
                                                    s.upper()               # Convert to uppercase
                                                    s.upper().count         # Function literal for 'how many times the argument appears in the string'

                   sorted(map(chr,range(65,91)),key=s.upper().count)        # Sort by that function
           ''.join(sorted(map(chr,range(65,91)),key=s.upper().count))       # Concatenate to string
           ''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1] # Step through by -1 (i.e. reverse string)

  lambda s:''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1] # Make it a function (`return` is implicit for lambdas)
f=lambda s:''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1] # Give it a name

2
Por otro lado, los comentarios en la explicación me dan cara de palmo. ¡Bienvenido a CS 101!
Izkata

66
@Izkata Lo importante es que te muestra en qué orden leer el código. Debido a que el mejor lugar para comenzar a leer código de golf rara vez es obvio, especialmente cuando se vuelve un poco más complicado o breve que esto.
Martin Ender

1
Hermosa presentación!
xnor

3
@Izk Mi objetivo era hacerlo comprensible para las personas que no conocen Python. Nunca haría comentarios como estos en un proyecto real.
undergroundmonorail

2
@imm No. countno es una variable ni nada, es una función literal. Tan genial como sería poder multiplicar el valor de retorno de una función -1pegando un -frente, esa no es una característica que tiene Python.
undergroundmonorail

15

Bash, 65 bytes

(tr a-z A-Z;echo {A..Z})|fold -1|sort|uniq -c|sort -nr|tr -dc A-Z

Ejemplo

$ bash etaoin.sh <<< "~AbaB BbaC"
BACZYXWVUTSRQPONMLKJIHGFED

Cómo funciona

(              #
  tr a-z A-Z   # Turn lowercase into uppercase letters.
  echo {A..Z}  # Print all uppercase letters.
) |            #
fold -1 |      # Split into lines of length 1.
sort |         # Sort those lines (required for piping to uniq).
uniq -c |      # Print the frequencies of all lines.
sort -nr |     # Sort by frequency (reversed).
tr -dc A-Z     # Remove everything that's not an uppercase letter.

1
Este no es un entorno local portátil, debe forzar LC_COLLATE = C (o más corto, LC_ALL).
Chris Down

66
La portabilidad de @ChrisDown generalmente no es una preocupación en las respuestas de código de golf.
Kevin

1
Sin portabilidad, lo que hace esta respuesta no está bien definido.
Chris Down

@ChrisDown: he probado algunas cadenas y algunas configuraciones regionales, pero no pude encontrar un ejemplo en el que uniq se porta mal para los caracteres alfabéticos. ¿Podrías mostrarme uno?
Dennis

@ChrisDown Este script es lo suficientemente portátil como para ejecutarse en OpenBSD usando las versiones BSD de fold, sort, tr, uniq, si el shell es bash o ksh93. Otros proyectiles, como zsh, no se expanden {A..Z}. Todos los entornos locales LC_COLLATE funcionan, porque OpenBSD solo tiene LC_COLLATE = C.
kernigh

12

Pyth 1.0.2 , 19 20

=ZUwsVm;dSm[cZkk)UG

Pruébelo aquí: http://ideone.com/fork/YlWpEJ

Obtenga más información sobre Pyth aquí: http://esolangs.org/wiki/Pyth

Ejemplo:

Basado en ETAOIN SHRDLU, su desafío es escribir el programa o la función más corta en cualquier idioma que genere las 26 letras del alfabeto inglés en función de su frecuencia en la entrada.

Da:

TENOHARSIULGFPYDCBWQMZXVKJ

Explicación:

=ZUw: Convierta la entrada a mayúsculas y almacene en Z.

sV: Imprime la suma del reverso de

m;d: Las últimas entradas de

S: Ordenados por su primera entrada, en orden creciente

m[cZkk): Las listas [recuento de k en Z, k]

UG: Para k en mayúsculas.

Equivalente a Python:

G='abcdefghijklmnopqrstuvwxyz'
Z=copy(upper(input()))
print(_sum(rev(_map(lambda d:d.pop(),sorted(_map(lambda k:_list(count(Z,k),k),upper(G)))))))

Esto no es una entrada, solo pensé que a la gente le gustaría verlo. En Pyth 1.0.4, el siguiente programa es una solución en 10 caracteres:

JUwo_cJNUG

Explicación:

JUw: Convierta la entrada a mayúsculas y almacene en J.

o: (Imprimir) Ordenar por

_cJN: -1 * (recuento de N en J)

UG: Más de N en letras mayúsculas.

No es una solución legal porque varios de los cambios de Pyth 1.0.2 a 1.0.4, incluida la adición de la ofunción Ordenar por, fueron en respuesta a este problema.


Le sugiero que actualice el enlace de Pyth a la página oficial de Pyth, si existe.
AL

@AL Esa es la página oficial de Pyth, hasta que puse una entrada de esolang.
isaacg 01 de

¿Por qué necesita almacenar la entrada en una variable Zpara referirse a ella una vez más tarde? ¿Simplemente poner la expresión para Zen su lugar hace que la entrada se lea varias veces?
xnor 01 de

@xnor La posición en la que se usa Z está dentro de una función lambda, porque está en el primer argumento de un mapa, por lo que debe guardarse en una variable. Si usas Uw, la entrada se leerá 26 veces.
isaacg 01 de

1
@AL Muy bien, Pyth está tanto en esolang como en github. El enlace de github está en la parte inferior de la página de esolang, que está vinculado en la respuesta. Github hace colorización de código.
isaacg

11

Javascript ( ES6 ) 119 117

Editar: (-2) Se eliminó la necesidad de toUpperCaseusar un RegEx que no distingue entre mayúsculas y minúsculas en la splitllamada.

a=prompt(f=x=>a.split(RegExp(x,'i')).length)
alert([...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'].sort((b,c)=>f(c)-f(b)).join(''))

Alternativa (misma longitud): condensó el recuento de clasificación y caracteres en una sola función.

a=prompt()
alert([...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'].sort(f=(b,c)=>c?f(c)-f(b):a.split(RegExp(b,'i')).length).join(''))

Como una función: 105 104

Editar: (-1) Condensó la ordenación y el recuento de caracteres en una sola función.

F=a=>[...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'].sort(f=(b,c)=>c?f(c)-f(b):a.split(RegExp(b,'i')).length).join('')

1
Técnica interesante
Matt

1
Salpicar una cuerda ... ¡delicioso!
Bergi

10

GolfScript, 22 caracteres

:?91,+-26>{.32+]?\-,}$

Pruébalo en línea.

Explicación:

  • :?asigna la cadena de entrada al símbolo ?. (Uso un símbolo de puntuación para que el siguiente número 91no se analice como parte del nombre del símbolo).
  • 91,construye una lista de los números del 0 al 90 (código ASCII de Z).
  • + agrega esta lista a la cadena de entrada, convirtiéndola de una matriz de códigos ASCII a una cadena (y convenientemente también eliminando la cadena de entrada de la pila).
  • -26>toma los últimos 26 caracteres de esta cadena, produciendo una cadena que contiene las letras mayúsculas ASCII de Aa Z.
  • El { }$aplica el bloque de código a todos los caracteres en la cadena de entrada, y clasifica los caracteres de acuerdo con el resultado.
  • Dentro del bloque de código, .duplica el carácter y 32+convierte la copia de mayúsculas a minúsculas. La ]recoge estos dos personajes en una matriz, ?\-toma la cadena de entrada almacenado en ?y elimina todas las apariciones de los personajes de la serie de ella, y ,los recuentos de la longitud de la cadena restante, que será la clave de ordenación. Los caracteres se ordenarán en orden ascendente por esta clave y, por lo tanto, en orden descendente por número de ocurrencias.

1
Parece que tuvimos más o menos la misma idea. Error menor: falta la letra Z. Debería ser 91,+-26>.
Dennis

@ Dennis: Ah, vaya. Solucionado, aunque ¿quién necesita esa carta de todos modos? :)
Ilmari Karonen 01 de

2
@IlmariKaronen Con base en los comentarios de la comunidad, modifiqué las reglas para permitir una nueva línea final (consulte la pregunta para obtener una descripción completa). Tu puntuación es ahora 22, en lugar de 25:)
Abraham

8

Haskell, 110 bytes

import Data.List
import Data.Char
a%f=compare(f a).f
f t=sortBy(% \c->length$filter((/=c).toUpper)t)['A'..'Z']

Ejemplo de uso:

λ> f "Based off ETAOIN SHRDLU, your challenge is to write the shortest program or function in any language that outputs the 26 letters of the English alphabet based on their frequency in the input."
"ETNAHORISULFGPBCDYMQWJKVXZ"

1
¿Qué pasa (/=c)y deshacerse de la 0-?
Lynn

@Mauris buena captura! Lo edité y afeité a otro personaje.
Flonk

6

Ruby 2.0, 53 caracteres

EDITAR : Se corrigió para que funcione correctamente con cadenas multilínea, ¡gracias @ durron597!

f=->s{$><<(?A..?Z).sort_by{|c|-s.upcase.count(c)}*''}

Crea una función llamada fque se puede usar de la siguiente manera:

f['jackdaws love my big sphinx of quartzzz']

Impresiones a STDOUT:

AZOSICGHEJKLMBFPQRDTUVWXYN

2
Esta respuesta no es correcta. Da esta respuesta: EITASUROLNCMPDVQGBHFKJWXYZpara el ejemplo en la pregunta
durron597

1
@ durron597 ¡Gracias, tienes razón! No estaba manejando cadenas multilínea correctamente: getsdevuelve una línea a la vez. Se puede solucionar cambiando getsa, gets$npero cambiarlo a una función es 1 char más corto.
Paul Prestidge

6

Perl, 54 46 bytes

ACTUALIZACIÓN: después de otras optimizaciones, podría reducirse a 46 bytes: (thx dennis for -n/ {}hack; perl goth chino para <=>-> -hack)

s/./$h{uc$&}++/eg}{say sort{$h{$b}-$h{$a}}A..Z

Es para correr con correr con perl -nE

Solución original (no necesita opciones especiales de Perl):

s/./$h{uc$&}++/egfor<>;print sort{$h{$b}<=>$h{$a}}A..Z

Verificado en Perl 5.8.3, 5.14.2

Si recibe una advertencia, separe egy forcon un espacio (+1 caracteres), si le importa

ejemplo de uso:

$ python -c 'import this' | perl -le 's/./$h{uc$&}++/egfor<>;print sort{$h{$b}<=>$h{$a}}A..Z' 2>/dev/null
ETAISONLRHPBUCDYMFGXVWKZJQ

EXPLICACIÓN: En cada carácter ( .) de cada línea de entrada ( for<>), aplicar una sustitución "patrón", que de hecho se evalúa como una expresión ( ebandera de la s///), que incrementos de un (upcased uc) carácter ( ./ $&es más corto que más evidente (.)/ $1) cuenta en el hash (no inicializado) ( %h). Luego, el hash de frecuencia de letras se usa en una función de comparación de clasificación para imprimir el alfabeto en mayúsculas en el orden correcto.


1
Mensajes más cortos y sin error:perl -ne 's/./$h{uc$&}++/eg}{print sort{$h{$b}<=>$h{$a}}A..Z'
Dennis

Dennis: muy interesante, parece un error tipográfico ... ¿qué es esto? He usado algunas variantes -ny END{}, pero siempre fueron más largas ... siéntase libre de actualizar la respuesta, si lo desea
mykhal

1
Sí, -nenvuelve while(<>){...}el código. Evito editar el código de otros usuarios. Demasiado fácil cometer un error, algunas cosas solo funcionan en algunas computadoras, etc.
Dennis

1
Joe: estaba hablando de la }{"inyección", no solo de la conocida -nopción. Uno no puede esperar que la cadena de código en realidad técnicamente está envuelto por la cadena de código bucle while antes de la ejecución, no sólo es justo que de alguna manera funciona como como si estuviera envuelto ..
mykhal

1
ahorre dos caracteres más: reemplace $h{$b}<=>$h{$a}con$h{$b}-$h{$a}
perl goth chino

5

R, 123 bytes

El código se mejora gracias a las sugerencias de @RichieCotton.

text <- "Based off ETAOIN SHRDLU, your challenge is to write the shortest program or function in any language that outputs the 26 letters of the English alphabet based on their frequency in the input."

f=function(x){b=plyr::count(toupper(strsplit(x,"")[[1]]));c=merge(LETTERS,b,all.x=T);paste(c[order(-c$freq),1],collapse="")}

f(text)

Salida:

> f(text)
[1] "ETNAHORISULFGPBCDYMQWJKVXZ"

1
@RichieCotton: He rechazado su edición sugerida dos veces ahora. No sé si se le notificará el motivo del voto de rechazo, por lo que si lee esto: proporcione mejoras de golf en los comentarios, para que el OP pueda revisarlos. He aquí por qué: meta.codegolf.stackexchange.com/a/1619/8478
Martin Ender

4

C ++, 185 183 179 177 bytes

No se espera que gane, por supuesto (¿puede C ++ ganar alguna vez?), Pero no obstante es un ejercicio divertido.

#include <algorithm>
#include <stdio.h>
int f[256],p;main(){for(p=65;p<91;p++)f[p]=p;while(~(p=getchar()))f[p&95]+=256;p=256;std::sort(f,f+p);while(p--)f[p]&95&&putchar(f[p]);}

Explicación:

#include <algorithm>         // for std::sort
#include <stdio.h>           // for getchar, putchar
int f[256],p;                // declare an array of count-prefixed chars, and a counter
main(){
    for(p=65;p<91;p++)       // 65 == 'A', 91 == the character after 'Z'
        f[p]=p;              // set the character for the slot
    while(~(p=getchar()))    // read characters until EOF
        f[p&95]+=256;        // increment the packed count for the character stripped of the 'lowercase bit'
    p=256;                   // start a countdown
    std::sort(f,f+p);        // sort the array
    while(p--)               // do the countdown
        f[p]&95 &&           // if the masked-off character is set...
          putchar(f[p]);     // print it
}

4

VBScript 181 109

Actualizado para usar un algoritmo completamente diferente. Beats JavaScript!

Bonita:

dim b(99):i=ucase(inputbox(k))
for y=65to 90
    c=chr(y)
    a=len(replace(i,c,k))
    b(a)=c+b(a)
next
msgbox join(b,k)

Golfizado:

dim b(99):i=ucase(inputbox(k)):for y=65to 90:c=chr(y):a=len(replace(i,c,k)):b(a)=c+b(a):next:msgbox join(b,k)

4

J 41 35 Bytes

(u:65+i.26)([\:[#/.~@,e.~#])toupper

Manifestación:

i=: 'This is a test to see whether this is still working'
(u:65+i.26)([\:[#/.~@,e.~#])toupper i
STIEHLORWAGKNBCDFJMPQUVXYZ

Explicación:

(u:65+i.26) & ( [ \: [ #/.~@,e.~#]) toupper) )
ABCDE...          |    |    |   |      uppercase the right argument
                  |    |    |   \copy from right only member from left
                  |    |     \append the left argument
                  |    \ Afterwards Count apperances of each letter
                  \ Sort the left according to the appearances

La clave es agregar la matriz izquierda, de modo que todas las letras estén disponibles y en orden. Una consecuencia divertida de usar un sustantivo como tercer diente del tenedor es que funciona como verbo y como frase.


4

Groovy - 130 123 115 112 98 92

Según el consejo de @ cfrick (¡dos veces!):

f={('A'..'Z').collectEntries{c->[c,it.grep(~/(?i)$c/).size()]}.sort{-it.value}*.key.join()}

Una pequeña prueba (robada descaradamente de @jpjacobs):

assert f('This is a test to see whether this is still working') == 
    'STIEHLORWAGKNBCDFJMPQUVXYZ'

Y la prueba propuesta también está pasando


1
La función necesita generar las 26 letras, no solo las presentes en la cadena de entrada.
algorithmshark

@algorithmshark, de hecho, mi error, corregido
Will Lp

f={('A'..'Z').collectEntries{c->[c,it.toUpperCase().findAll(c).size()]}.sort{-it.value}.keySet().join()}para 104
cfrick

1
otros 6 bytes: en it.grep(~/(?i)$c/)lugar deit.toUpperCase().grep(c)
cfrick

@cfrick ¡Guau! ¡Gracias de nuevo! Eso me toUpperCaseestaba molestando muchísimo.
Will Lp

4

SAS - 217 (creo)

La entrada debe colocarse en la línea después de la declaración cards4, o en las tarjetas perforadas apropiadas para su sistema. Creo que este enfoque ahorra algunos caracteres en lugar de intentar citar la entrada.

data a;
input;
S = upcase(compress(_INFILE_,,'ak'));
do i=1 to length(S);
l=substr(S,i,1);
output;
end;
cards4;
;;;;
run;
proc sql;
select l into :o separated by '' from
(select l, 1/count(l) as f from a group by l) order by f;
quit;

Soy consciente de que esto no cumple con la especificación completa, ya que solo devuelve caracteres que aparecen en la cadena de entrada. Podría necesitar repensar esto un poco.


No cumple con las especificaciones, pero sigue siendo genial, así que +1: D
gato

4

AppleScript, 278

Noté que eso "a" = "A"es cierto en AppleScript. Puedo usar esto en el código de golf, pero el resto del script es demasiado prolijo. Usé AppleScript 1.8.3.

Esto define una función f. Si agrega f("a string")en la parte inferior del script y lo ejecuta en el Editor de Script, mostrará el resultado.

on c(n)
ASCII character(64+n)
end
on f(s)
set{a,r}to{{},""}
repeat with i from 1 to 26
set j to 0
repeat with b in s
if b&""=c(i)then set j to j+1
end
set a to a&j
end
repeat with j from 0 to(count s)
repeat with i from 1 to 26
if a's item i=j then set r to c(i)&r
end
end
r
end

Formateado y comentado:

-- Returns nth letter of alphabet.
on c(n)
    ASCII character (64 + n)
end c

-- Returns letters in s sorted by frequency.
on f(s)
    -- a: list of letter counts
    -- r: resulting string
    set {a, r} to {{}, ""}

    -- For each letter from A to Z,
    -- count letters in string s.
    repeat with i from 1 to 26
        set j to 0
        repeat with b in s
            -- Can't use b = c(i), because
            -- b is a reference to a string
            -- and = never dereferences its
            -- operands. Get contents of b,
            -- here by coercing b to string.
            if b & "" = c(i) then set j to j + 1
        end repeat
        -- Set item i of a to count j.
        set a to a & j
    end repeat

    -- Sort letters by frequency.  Do a counting sort
    -- because AppleScript lacks a sort command.
    repeat with j from 0 to (count s)
        repeat with i from 1 to 26
            if a's item i = j then set r to c(i) & r
        end repeat
    end repeat
    r
end f

-- Example call:
f("Now is the time for all good men to come to the aid of their country.")
-- Result: "OTEIRNMHLFDCAYWUSGZXVQPKJB"

3

VBScript 157156 bytes

Editar: cambió msgbox (p) a msgbox p

Más legible:

s=ucase(InputBox(z))    'z is empty.
L=len(s)
Dim a(255)
for i=1to L
    x=asc(mid(s,i))
    a(x)=a(x)+1
next
for t=0to L
    For i=65To 90
        If a(i)=t then p=chr(i)&p
    next
next
msgbox p

Golfizado: (155 caracteres + 1 retorno de carro)

s=ucase(InputBox(z)):L=len(s):Dim a(255):for i=1to L:x=asc(mid(s,i)):a(x)=a(x)+1:next:for t=0to L:For i=65To 90:If a(i)=t then p=chr(i)&p
next:next:msgbox p

Lo tenía en 171 anteriormente con un código que me pareció más interesante, pero cómodamente el método de clasificación de Drei es más corto y requiere len (s), lo que hace un "para" más corto que el "while" para el primer bucle. (bostezo)

's=UCase(InputBox(Z))&8 'just need any extra character.  0-7 don't work because &7 is octal

s=UCase(InputBox(Z)) 'nevermind
Dim a(999)
While Len(s)
    x=Asc(s) 'returns ascii of first char
    a(x)=a(x)-1 'going negative saves a character later...
    s=Mid(s,2) 'doesn't care if you run out of string
Wend
for j=1 to 26 'this used to be   While Len(p)<26
    For i=65To 90
        If a(i)<a(y) Then y=i 'it is barely not worth it to do a(i)+a(i+32)>a(y) here to skip the ucase() above
    Next
    p=p&Chr(y)
    a(y)=1 'if I didn't go negative this would have to be -1.  arrays default to 0.
Next
MsgBox(p)

¡Aprendí algunos trucos geniales de esta publicación! Gracias por la mención también. Una cosa: creo que for t=0debería serlo for t=1, de lo contrario siempre se imprime el alfabeto completo.
comfortableablydrei

1
@comfortablydrei Se requiere imprimir todo el alfabeto. "El programa / función debe mostrar solo las 26 letras MAYÚSCULAS del alfabeto inglés, incluidas las que no aparecen en la entrada"
JesterBLUE

whoa perdí esa. Entonces es mi error. ¡Gracias!
comfortableablydrei

3

J - 38 35 caracteres

Una función que toma la entrada a la derecha como una cadena. No es un ganador, pero fue divertido escribir.

(u:65+i.26)([\:[#/.~@,e.~#])toupper

Explicado:

  • toupperes un verbo en la biblioteca estándar que encierra una cadena. Eso se convierte en el argumento correcto del verbo, mientras que el argumento izquierdo es el alfabeto: los puntos de código ASCII 65 a 90.

  • [y ,e.~#])selecciona ( #) esas letras en el argumento derecho ( ]) que son elementos de ( e.~) el izquierdo, y luego antepone ( ,) el argumento izquierdo ( [). A saber, mantenemos solo los caracteres en mayúscula y agregamos una sola copia del alfabeto al final, para asegurarnos de que los atrapamos a todos.

  • #/.~@luego da las frecuencias de cada personaje. Sucede que esto se da en orden alfabético, por lo que inmediatamente podemos ordenar ( \:) el alfabeto (el argumento izquierdo [).

Un ejemplo perezoso rápido a continuación. No dude en probarlo por ti mismo en tryj.tk .

   (u:65+i.26)([\:[#/.~@,e.~#])toupper 'Based off ETAOIN SHRDLU, your challenge is to write the shortest program or function in any language that outputs the 26 letters of the English alphabet based on their frequency in the input.'
ETNAHORISULFGPBCDYMQWJKVXZ

3

T-SQL 178

Básicamente, esta es mi solución VBScript pero implementada en SQL.

Esto es abuso de salida XML para concatenar una columna. En uso práctico, se puede unir a una tabla externa para emular GROUP_CONCATfunciones en MySQL y otros.

Declarando la @variable:

DECLARE @ CHAR(1024)= 'enter your text here';

Código:

with y AS(
    SELECT UPPER(@)i,0l,91y
    UNION ALL
    SELECT i,len(replace(i,char(y-1),'')),y-1
    FROM y
    WHERE y>65
)
SELECT LTRIM(
(
    SELECT char(y)
    FROM y
    WHERE y<91
    ORDER BY l
    FOR XML PATH(''))
)

3

Perl, 78 bytes

undef$/;$i=<>;$r{$i=~s/$_//gi}.=$_ for A..Z;print$r{$_}for sort{$b<=>$a}keys%r
  • Solo las 26 letras mayúsculas ASCII sin ningún espacio en blanco se emiten en orden de frecuencia.
  • Los caracteres atados se dan en orden alfabético.

Resultado para el ejemplo en la pregunta:

EITUSALNROMCDPVGQBFHJKWXYZ

Sin golf:

# read input
# ----------
undef $/; # disable input separator
$i = <>;  # $i holds the complete input as one string

# analyze
# -------
# For each uppercase letter (A upto Z) its occurences are counted
# via the number of substitutions made by s/$_//gi. The lowercase
# letter is included via modifier "i".
# 
# The occurrence count is then used as key for hash %r.
# The uppercase letter is appended to the value of that hash entry.
$r{$i =~ s/$_//gi} .= $_ for A..Z;

# output
# ------
# The hash keys are sorted numerically in reverse order by
# the specified sort function.
print $r{$_} for sort {$b<=>$a} keys %r

Esto podría funcionar para el ejemplo, bot no, por ejemplo, para la echo -e 'x\ny\n\nz\n'salida, que debería regresar XYZABCDEFGHIJKLMNOPQRSTUVW, sino que rinde XYABCDEFGHIJKLMNOPQRSTUVWZ. Adivina por qué .. :)
mykhal

@mykhal: corregido.
Heiko Oberdiek

3

PHP - 105 bytes

<?preg_filter(~‹§æ“Ö¢‹ö,'$f[$0&fl]++',join('',range(a,z)).$argv[1]);arsort($f);foreach($f as$l=>$F)echo$l;

Aquí hay un hexdump, debido a los caracteres especiales:

0000000 3c 3f 70 72 65 67 5f 66 69 6c 74 65 72 28 7e dc
0000010 a4 be d2 85 a2 dc 9a 2c 27 24 66 5b 24 30 26 df
0000020 5d 2b 2b 27 2c 6a 6f 69 6e 28 27 27 2c 72 61 6e
0000030 67 65 28 61 2c 7a 29 29 2e 24 61 72 67 76 5b 31
0000040 5d 29 3b 61 72 73 6f 72 74 28 24 66 29 3b 66 6f
0000050 72 65 61 63 68 28 24 66 20 61 73 24 6c 3d 3e 24
0000060 46 29 65 63 68 6f 24 6c 3b                     
0000069

Y una versión un poco menos golfizada:

<?
preg_filter(           // regular expression
  "#[A-z]#e",          // matches every letter + 'eval' flag
  '$f[$0&fl]++',        // so this code runs for every letter
                       // $f is an array whose indices are uppercase letters
                       //   and whose values represent the number of occurences
                       // lowercase is converted to uc with the bitwise and
                       //   fl is 11011111 in binary, every bit except for 32's is set
  join('', range(a,z)) // adding abcdefghijklmnopqrstuvwxyz to the input
    .$argv[1]);        //   because not all letters have to appear in the input
arsort($f);            // sort $f in reverse, maintaining indices
foreach($f as$l=>$F)   //
  echo$l;              // print each index in order

Ejemplo:

 $ php etaoin_shrdlu.php "This function sorts an array such that array indices maintain their correlation with the array elements they are associated with."
 ATIRESHNOCYUWMDLFXZBVGPQKJ

¿Cómo funcionan los personajes especiales en el preg_filter()trabajo?
Abraham

3
En PHP ~ es el operador NOT bit a bit, y también puede aplicarlo a cadenas, en cuyo caso funciona en todos los caracteres. Además, PHP se complace en analizar cadenas de texto como literales de cadena dado que no hay caracteres especiales en ellas (por ejemplo, operadores, $ para variables, punto y coma, paréntesis ...). Por lo tanto, escribir ~ ‹§æ“ Ö ¢ ‹ö (la versión invertida a nivel de bits) en lugar de" # [Az] #e "guarda un byte, ya que no es necesario citarlo.
Aurel Bílý

Ah gracias. Tiene sentido ahora.
Abraham

1
En la medida en que cualquier cosa en PHP tiene sentido. Santo moly.
esponjoso

echo join(array_keys($f));puede guardar un byte
Tito

3

C # en LINQPad - 203 bytes

Tomé un enfoque diferente a la respuesta de Logan Dam. Primero me aseguré de que cada carácter en la cadena de entrada esté ordenado por su apariencia y solo exista una vez en la cadena de salida. Después de eso, agregué todos los caracteres faltantes del alfabeto a la cadena de salida.

void e(string i){var a="";foreach(var d in i.ToUpper().GroupBy(x=>x).OrderByDescending(u=>u.Count()))if(d.Key<91&&d.Key>64){a+=d.Key;}for(int x=65;x<91;x++)if(!a.Contains((char)x)){a+=(char)x;}a.Dump();}

Lamentablemente, no superaría la respuesta de Logan Dam si lo hubiera hecho en Visual Studio.

Versión más legible:

void e(string i)
    {
        var a = "";
        foreach (var d in i.ToUpper().GroupBy(x => x).OrderByDescending(u => u.Count()))
        {
            if (d.Key < 91 && d.Key > 64)
            {
                a += d.Key;
            }
        }
        for (int x = 65; x < 91; x++)
        {
            if (!a.Contains((char)x))
            {
                a += (char)x;
            }
        }
        a.Dump();
    }

Yay, más amor LINQ! : D
señora

3

C # (y LINQ) 255 226 210 Bytes

Usando el consejo de Patrick Huizinga, la sintaxis de la consulta ahora es más corta:

namespace System.Linq{class P{static void Main(string[]a){Console.Write((from c in(a[0]+"ABCDEFGHIJKLMNOPQRSTUVWXYZ").ToUpper()where c>'@'&&c<'['group c by c into g orderby-g.Count()select g.Key).ToArray());}}}

Explicación:

Console.Write(
    (from c //declare our range variable
       in (a[0] + "ABCDEFGHIJKLMNOPQRSTUVWXYZ").ToUpper() //declare the datasource
     where c > '@' && c < '[' //include only letters
     group c by c into g //run of the mill group by
     orderby -g.Count() //order by descending
     select g.Key //we only want the actual letters
     ).ToArray() //mash it all into an array
  );

Sintaxis del método equivalente (217):

namespace System.Linq{class P{static void Main(string[]a){Console.Write((a[0]+"ABCDEFGHIJKLMNOPQRSTUVWXYZ").ToUpper().GroupBy(c=>c).OrderBy(c=>-c.Count()).Where(c=>c.Key>'@'&&c.Key<'[').Select(c=>c.Key).ToArray());}}}

Publicación original:

namespace System.Linq{class P{static void Main(string[]a){(a[0]+"ABCDEFGHIJKLMNOPQRSTUVWXYZ").ToUpper().GroupBy(c=>c).OrderByDescending(c=>c.Count()).Where(c=>c.Key>'@'&&c.Key<'[').ToList().ForEach(c=>Console.Write(c.Key));}}}

Esta es mi primera presentación y debería estar haciendo cosas en el trabajo, pero parecía muy divertido porque sentí que podía participar por una vez.

Explicación:

(a[0] + "ABCDEFGHIJKLMNOPQRSTUVWXYZ") //ensure each character appears once
  .ToUpper()
  .GroupBy(c => c) //get access to .Count()
  .OrderByDescending(c => c.Count())
  .Where(c => c.Key > '@' && c.Key < '[') //exclude anything other than letters
  .ToList() //Only lists have a .ForEach() :(
  .ForEach(c => Console.Write(c.Key)); //print output

Nunca uso la sintaxis del método para LINQ, por lo que esta fue una experiencia de aprendizaje para mí :) también pensando en eso ahora podría ahorrar 2 bytes reemplazando los literales de caracteres con sus contrapartes enteras, pero, meh.

Acortado gracias a los consejos de ProgramFOX y Num Lock :)

La sintaxis de consulta equivalente (un poco más larga):

(from c in (a[0]+"ABCDEFGHIJKLMNOPQRSTUVWXYZ").ToUpper() where c>'@'&&c<'[' group c by c into g orderby g.Count() descending select g.Key).ToList().ForEach(c=>Console.Write(c));

1
En un primer vistazo, podría guardar una gran cantidad de caracteres al nombrar su clase solo en Plugar de Programy en string[]alugar de string[] argsy en c=>...lugar de (c)=>....
Bloq Num

En lugar de dos usingdeclaraciones, también puede poner su clase dentro del System.Linqespacio de nombres y eliminar ambas usando declaraciones. Luego puede guardar algunos caracteres y seguirá funcionando bien.
ProgramFOX

@NumLock Correcto, ni siquiera pensé en eso :) @ProgramFOX que no me ahorrará nada porque namespacees más largo que usingy los dos {}s adicionales me costarán más.
señora

1
namespace System.Linq{}es claramente más corto que using System;using System.Linq;solo mirarlo. La idea es omitir ambos por usingcompleto.
Num Lock el

Ahh, sí, elimina ambos, tienes razón, estaba pensando que solo eliminó el uno. Gracias.
señora

3

C ++ 701 322 232 bytes

Primera versión 701 bytes (uso idiomático de STL)

#define _HAS_TRADITIONAL_STL 1
#include <numeric>
#include <iostream>
#include <iterator>
#include <string>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#define ALL(x) x.begin(), x.end()
using namespace std;
typedef istream_iterator<char> iic;typedef pair<int, char> pic;map<char, int> c;set<pic> d;
void f1(char x) {c[x]--;}
void f2(const pic &p) {d.insert(make_pair(p.second, p.first));}
int main(){string s(26, 0);stdext::iota(ALL(s), 65);copy(ALL(s), ostream_iterator<char>(cout));transform(iic(cin), iic(), back_inserter(s), toupper);for_each(ALL(s), f1);for_each(ALL(c), f2);transform(ALL(c2), ostream_iterator<char>(cout), select2nd<pic>());}

Versión limpia ampliada:

#define _HAS_TRADITIONAL_STL 1
#include <numeric>
#include <iostream>
#include <iterator>
#include <string>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
using namespace std;

typedef istream_iterator<char> iic;
map<char, int> counts;
set<pair<int, char> > counts2;

void docount(char ch) { counts[ch]--; }
void toCounts2(const pair<char, int> &p) { counts2.insert(make_pair(p.second, p.first)); }

int main()
{
    string s(26, 0);
    stdext::iota(s.begin(), s.end(), 65);
    transform(iic(cin), iic(), back_inserter(s), toupper);
    for_each(s.begin(), s.end(), docount);
    for_each(counts.begin(), counts.end(), toCounts2);
    transform(counts2.begin(), counts2.end(), ostream_iterator<char>(cout), select2nd< pair<int, char> >());
}

La idea es demostrar un programa C ++ "adecuado" sin ningún truco. Ignora la repetitiva y el hecho de que esto solo se compila en VC ++

Explicacion:

Rellenamos de la A a la Z en una cadena con iota () , esto asegura que cuando contamos las ocurrencias, cada carácter aparece incluso si no está en la entrada.

transform () copia carácter por carácter de la entrada estándar y lo coloca al final de s después de llamar a toupper () en cada uno

El recuento de cada personaje se reduce en el mapa (al mantener los recuentos negativos podemos tener un orden descendente sin código adicional)

Las entradas del mapa de conteos se copian en un conjunto de pares, intercambiando (char, count) a (count, char). Como los conjuntos están ordenados, los ordenamos disminuyendo el recuento de frecuencia

Finalmente copiamos el contenido del conjunto a estándar, usando transform, y usando select2nd () para seleccionar solo el segundo miembro del par.

El código es bastante legible. Una solución C ++ 11 se vería mucho más bonita, ya que podemos usar lambdas

Versión C ++ 11: no se necesitan lambdas, pero las funciones automáticas y basadas en rango hacen las cosas muy limpias (ahora que lo pienso, puede hacer algo muy similar con C ++ 98 normal)

#include<iostream>
#include<iterator>
#include<map>
#include<set>
using namespace std;int main(){istream_iterator<char> b(cin),e;map<char,int> c;set<pair<int,char>> d;for(char i='A';i<='Z';++i){--c[i];}for(auto i=b;i!=e;++i){c[toupper(*i)]--;}for(auto p:c){d.insert(make_pair(p.second,p.first));}for(auto p:d){cout<<p.second;}}

Versión ampliada:

#include <iostream>
#include <iterator>
#include <map>
#include <set>
using namespace std;
int main()
{
    istream_iterator<char> b(cin), e;
    map<char, int> c;
    set<pair<int, char>> d;
    for(char i = 'A'; i <= 'Z'; ++i) {--c[i];}
    for(auto i = b; i != e; ++i) {c[toupper(*i)]--;}
    for(auto p : c) { d.insert(make_pair(p.second, p.first)); }
    for(auto p : d) { cout << p.second; }
}

Próxima iteración (por qué leer de stdin cuando tenemos argv):

#include <set>
#include <iostream>
int c[256];int main(int n, char **s){std::set<std::pair<int,char>> d;while(*s[1]){c[toupper(*s[1]++)]--;}for(n=65;n<92;++n){d.insert(std::make_pair(--c[n],n));}for(auto p:d){std::cout<<p.second;}}

Versión ampliada:

#include <set>
#include <iostream>
int c[256];
int main(int n, char **s)
{
    std::set<std::pair<int, char>> d;
    while (*s[1])
    {
        c[toupper(*s[1]++)]--;
    }
    for (n = 65; n < 92; n++)
    {
        d.insert(std::make_pair(--c[n], n));
    }
    for (auto p : d)
    {
        std::cout << p.second;
    }
}

3

Gelatina , 9 bytes (no competitiva)

ØAŒuċ¥@ÞU

Explicación

ØAŒuċ¥@ÞU  Main Link
       Þ   Sort
ØA         The uppercase alphabet by
  Œuċ¥@    number of occurrences in the input:
  Œu       Uppercase
    ċ      Count occurrences
     ¥     Grammar: Last two links as a dyad
      @    Swap arguments
        U  Reverse (because sort sorts up)

Esto se lee como "ordenar el alfabeto en mayúsculas por el número de ocurrencias en la entrada en mayúscula, invertida", que es una traducción bastante literal del desafío: P

Pruébalo en línea!

Este desafío estaba vinculado a Jelly HyperTraining donde resolvimos el desafío. Publiqué esto porque fui el primero en llegar a 10 bytes.

-1 byte gracias a Erik the Outgolfer (profesor de JHT)


9 bytes:ØAŒuċ¥@ÞU
Erik the Outgolfer

@EriktheOutgolfer Oh genial, gracias!
HyperNeutrino

2

C ++ 377

Implementa qsort usando el recuento de letras en la matriz n para ordenar el alfabeto en la matriz A. Ejecutar a través de la línea de comando: golf.exe < in.txt

int n[26],c,k,N;
char A[26];
int C(const void*a,const void*b)
{
int i=(int)(*(char*)a -'A');
int j=(int)(*(char*)b -'A');
return n[j]-n[i];
}
int main()
{
for(;k<26;k++)
{
A[k]=k+'A';
}
N=sizeof(A);
c=getchar();
while(c>0)
{
c=toupper(c);
c=c-'A';
if(c>=0&&c<26)n[c]++;
c=getchar();
}
qsort(A,N,1,C);
for(k=0;k<N;k++)
{
putchar(A[k]);
}
return 0;
}

2

C, 117 (119) bytes

x[256];m=1;char c;main(){while(c=getchar()+1)++x[c-1&95];for(;m=x[++c]<x[m]?m:c;x[m<65|m>90||c?m*!c:putchar(m)]=-1);}
  • Algunas entradas que contienen códigos ASCII> = 128 aumentarán incorrectamente las frecuencias de letras. Para solucionar esto, reemplace la constante 95con 223, a un costo de 1 byte adicional.
  • Esto terminará antes en las entradas que contienen el carácter con el código ASCII 255. Para arreglar esto al costo de 1 byte adicional, cambie char c;a just c;y ++cto c=c+1%255.

2

PowerShell - 139 caracteres

Primero, no soy un experto en PowerShell. Estoy bastante seguro de que hay más cortos que esto. Pero estaba contento con eso y decidió compartir.

$a = Read-host
$b = ($a.ToUpper() -replace '[^A-Z]','').ToCharArray() + (65..90|%{[char[]]$_})|Group|sort Count -desc|%{$_.Name}
-join $b

Cómo funciona:

$a = Read-host            # read from stdin and save into a string var $a
$a.ToUpper()              # Convert the string to UPPERCASE
-replace'[^A-Z]',''       # Remove all non A-Z characters from the str
(...).ToCharArray()       # Convert the inner object (string) to a Char Array
+  (65..90|%{[char[]]$_}) # Create another char array with A-Z chars expanded, 
                          #  and append it to the previous one.
|Group                    # Group the char array by value for each element, 
                          #  consolidates them and count each char occurrence. Example:
                          #  Count | Name
                          #  ----- | -----
                          #      4 | B
                          #      1 | F
                          #      2 | C 
                          #     .. | ..
                          # 
|sort Count -desc         # Sorts the previous hash-table by the 'Count' column 
                          #   in desc ordering
|%{$_.Name}               # Grab only the 'Name' column from the previous sorted hash-table. 
                          # The retuslt obj will be a simple char array again, 
                          #   with the letters in the desired order
$b = (...)                # Saves the resulting char array into a new variable $b
-join $b                  # join the resulting char array elements into a single 
                          #   string, and print it to stdout. 

2

Ceilán , 98 bytes

String f(String s)=>String(('A':26).sort(byDecreasing((Object c)=>s.uppercased.count(c.equals))));

2

APL, 26 20 caracteres

⎕a[⍒+/⎕a∘.=('\w'⎕r'\u0')⍞]

⎕a[⍒+/⎕a∘.=1(819⌶)⍞]

-6 gracias a Adam.


1
('\w'⎕r'\u0')1(819⌶)
Adám
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.