Imprime el alfabeto cuatro veces


37

El programa debe imprimir el alfabeto cuatro veces: primero en el orden alfabético normal, segundo en el orden de un teclado qwerty, tercero en el orden de un teclado dvorak y, por último, en orden alfabético inverso. La salida debería parecerse a esto:

abcdefghijklmnopqrstuvwxyz
qwertyuiopasdfghjklzxcvbnm
pyfgcrlaoeuidhtnsqjkxbmwvz
zyxwvutsrqponmlkjihgfedcba

La salida no distingue entre mayúsculas y minúsculas, y puede agregar u omitir nuevas líneas o espacios donde lo desee.

El truco : el programa debe tener menos de 104 caracteres o, en otras palabras, menos de la longitud del alfabeto por cuatro.

Aceptaré la respuesta con el código más corto, a menos que vea algo realmente inteligente o interesante que me impresione más.

EDITAR: aceptaré la respuesta más corta el miércoles 4/27/2011.

EDIT2: ¡ Y el ganador es (como siempre) Golfscript en 64 caracteres! El segundo lugar , que está detrás de solo tres caracteres, también está en Golfscript, con 67 caracteres, seguido por Bash en el tercer lugar con 72 caracteres.

Pero había algunos otros que quería mencionar, como este , que, según su definición, solo usaba 52 "caracteres", y este donde lo escribió en un idioma que creó.

Hubo algunas personas que rompieron una regla no escrita y no calificaron, pero las mencionaré solo por su forma de pensar sin la caja.


11
Considera usar una recompensa por una respuesta que te haya impresionado. Creo que aceptar una respuesta en un código de golf siempre debe ser el criterio natural (es decir, la longitud).
Joey

Perdí usando Tcl: tio.run/…
sergiol

Respuestas:


16

Python 2, 97 caracteres

q="qwertyuiopasdfghjklzxcvbnm"
a="".join(sorted(q))
print a,q,"pyfgcrlaoeuidhtnsqjkxbmwvz",a[::-1]

¡Ordenar QWERTY y volver a convertir de la lista a cadena es más corto que el alfabeto mismo! *

Otra opción para generar el alfabeto en menos caracteres que el alfabeto en sí:

print map(chr,range(65,91))

Aunque esto imprime una lista de caracteres de Python.

No hay mucho que hacer aquí en cuanto a la compresión de datos; intercalar las letras en 5 bits solo ahorra 39 caracteres, lo que no es mucho si luego tiene que desatascarlos (y aún tiene que representar los bytes literalmente); parece que zlib (solo como ejemplo) ahorra menos de 20 bytes; codificar la secuencia como una lista de deltas para la siguiente letra todavía toma 5 bits para cada delta, porque el más grande en esta secuencia es -22:

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
 1, 1, 1, 1, 1, 1, 1, -9, 6, -18, 13, 2, 5, -4, -12, 6, 
 1, -15, 18, -15, 2, 1, 2, 1, 14, -2, -21, 19, -20, 12, 
 -1, 3, 9, -19, 1, -4, 15, -6, -11, 14, -10, 16, -12, -5, 
 4, 12, -6, 5, -2, -7, 1, 13, -22, 11, 10, -1, 4, 0, -1, 
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]

* Aunque solo un poco.


1
Python 3.5:q="qwertyuiopasdfghjklzxcvbnm";a=sorted(q);print(*a,q,"pyfgcrlaoeuidhtnsqjkxbmwvz",*a[::-1])
Veedrac

15

PHP, 100 bytes

Como ISO 8859-1:

<?=base64_encode("i·yø!9%z)ª»-ºü1Ë:°z»rº*)jÇ_ä<\½¹æ§'àr¹Z¡ë¢vg²¨äŹ°¿<òÇî¶Êê¦æHâÞuÆÚ");

Para reproducir de manera confiable,

printf '<?=base64_encode("' > 4times.php
printf abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvzzyxwvutsrqponmlkjihgfedcba | base64 -d >> 4times.php
printf '");' > 4times.php

55
Esa es una forma interesante de hacerlo. Todos los demás son variaciones de la misma idea, pero esta es un poco diferente.
Peter Olson el

No creo que esto deba contar; la pregunta está etiquetada como "complejidad de Kolmogorov" y especifica "104 caracteres", lo que significa que deberíamos discriminar lo que consideramos un personaje. De lo contrario, definiré mi propia codificación de caracteres con un solo carácter que se asigna al ASCII para un programa completo que resuelve el problema, y ​​luego lo decodificará.
Adrian Petrescu

2
@Adrian Petrescu: eso se resuelve fácilmente al exigir que la codificación ya exista en el momento en que se plantea el desafío.
Lowjacker

@Lowjacker Claro, pero esa parece ser una forma bastante arbitraria de resolver esto.
Adrian Petrescu

55
@Adrian, la ventaja de Unicode cuando se usan caracteres vs bytes ha sido reconocida durante mucho tiempo. En mi opinión, no tiene sentido que la pregunta se etiquete Kolmogorov mientras se solicitan caracteres. Debería estar contando bytes. Depende del autor de la pregunta tener cuidado con estos términos.
gnibbler

10

Rubí 1.9, 88 87 84 80

puts b=[*?a..?z],:qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz,b.reverse

10

Bash, 82

echo {a..z}
echo qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz
echo {z..a}

9

Python, 97 96 "personajes"

Tomando su uso de la palabra "caracteres" generosamente, aquí hay algunas python que usan caracteres unicode de 16 bits para codificar 3 caracteres normales cada uno. El programa tiene un total de 96 caracteres, 35 de los cuales son los personajes Unicode más extraños que he visto.

for i in range(104):print chr((ord(u'ࠠᒃ⃦ⵉ��割廕��匓�เ᳅ⵉૹ�懬ࣅű傎ᱨ�⤰〷�弙劶��ⶍKᓇࡤ^A'[i/3])>>i%3*5&31)+97),

No estoy seguro de que la basura Unicode vendrá correctamente, así que aquí hay un programa de Python para generar el programa de Python anterior:

#!/usr/bin/python                                                                                                                                                                 
import codecs
f=codecs.open('alpha.py','w','utf-8')
f.write('#!/usr/bin/python\n')
f.write('# coding=utf-8\n')
f.write('for i in range(104):print chr((ord(u\"')
S='''abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvzzyxwvutsrqponmlkjihgfedcbaa'''
for i in xrange(0,104,3):
 n=32*32*(ord(S[i+2])-97)+32*(ord(S[i+1])-97)+ord(S[i+0])-97
 f.write(u'%c'%n)
f.write('"[i/3])>>i%3*5&31)+97),\n')

9

Bash, 72

echo {a..z} qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz {z..a}

EDITAR: eliminado tr -d.

Créditos: Alexander, Roger.


2
Las reglas le permiten omitir |tr -d ' ', guardar 10 caracteres y hacer que esta versión sea líder en el momento de escribir :-)
Alexander Gladysh

@Alexander, Cool ;-) no lo sabía. Gracias a @Roger por señalarme en la dirección correcta.
asoundmove

Estaba tratando de encontrar una solución más elegante con algún tipo de polinomio con poderes de primos y módulo (o, en otras palabras, encontrar una función de permutación lo suficientemente simple que funciona a través de esa secuencia) ... pero no puedo pasar el tiempo requerido para tal solución, así que lo dejaré así. Además, sería bastante difícil de expresar de manera concisa.
asoundmove

9

Golfscript, 64 caracteres

"qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz".$2%\1$-1%

Nota: también 64 bytes. En realidad, jugar con Unicode y los cambios de base parece contraproducente porque basees una palabra clave demasiado larga.


6

Windows PowerShell, 89

No es particularmente bueno, pero al menos más corto que la cadena de salida:

[char[]](65..90)
'qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz'
[char[]](90..65))

Way shorter now that I saw that there is a relaxation on whitespace. And a little shorter still, if I ignore case which I'm allowed to.


2
Tienes un extra )allí. Debería ser 88.
Iszi

5

Golfscript, 76 , 67 caracteres

123,97>+."qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz"\-1%

Use 123,97>+para generar el alfabeto inicial.
Ventero el

Gracias Ventero, de hecho lo vi en tu otra publicación el otro día.
USTED

4

CI - 92 caracteres

'a(1p'z((,0(4d)(.$)<)$)(0c0c.1+2p$.)>)$)qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz

CI ("Compilador / Intérprete") es un lenguaje simple basado en pila que creé para el desafío "Intérprete de autointerpretación" (link to answer). I posted that answer about two hours before this challenge was posted. It's no GolfScript (which I still haven't gotten around to learning), as my goal was to make the interpreter short.

Este programa debe pasarse al ciintérprete a través de la entrada estándar. El intérprete trata los caracteres después de una terminación )como entrada al programa. Mi lenguaje no admite literales de cadena, por lo que stdin está tomando su lugar.


3

Python 2.7.X - 103 caracteres irónicamente ...

a='abcdefghijklmnopqrstuvwxyz'
print a,'qwertyuiopasdfghjklzxcvbnm pyfgcrlaoeuidhtnsqjkxbmwvz',a[::-1]

Resulta que generar el alfabeto en python requiere más caracteres que codificarlo. Como lo hace importar el alfabeto. Tengo que amar un lenguaje centrado en la legibilidad a veces.


1
No necesita el espacio entre las cadenas QWERTY y DVORAK, sería 1 carácter menos.
Lowjacker

Es cierto, pero Python agrega automáticamente un espacio entre cada elemento en la lista de impresión separada por comas, por lo que el espacio es mi sacrificio personal para la alteración de la salida legible.
Arrdem

Podrías usar el en +lugar de ,y ahorrar ese espacio.
Martin Ueding

3

C - 133 caracteres

Versión acortada de Casey:

main(i){char a[105];strcpy(a+26,"qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz");for(i=0;i<26;)a[i]=a[103-i]=i+++65;puts(a);}

Espacio en blanco:

main(i) {
    char a[105];
    strcpy(a+26, "qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz");
    for(i=0;i<26;)
        a[i]=a[103-i]=i+++65;
    puts(a);
}

Salida transpuesta

Aquí hay una versión que transpone la salida, por diversión. 134 caracteres.

main(i){char*a="qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz";for(i=0;i<26;i++,a++)printf("%c%c%c%c\n",i+65,*a,*(a+25),90-i);}

Espacio en blanco:

main(i){
  char*a="qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz";
  for(i=0;i<26;i++,a++)
    printf("%c%c%c%c\n",i+65,*a,*(a+25),90-i);
}

Huellas dactilares:

AqmZ
BwpY
CeyX
DrfW
EtgV
FycU
GurT
HilS
IoaR
JpoQ
KaeP
LsuO
MdiN
NfdM
OghL
PhtK
QjnJ
RksI
SlqH
TzjG
UxkF
VcxE
WvbD
XbmC
YnwB
ZmvA

Todavía no encaja, por supuesto.
Alexander Gladysh

1
declarando icomo global y colocando strcpy(...)en el primer bloque del bucle for, obtienes 129. aunque todavía es demasiado.
bebe

3

J

x=:(97+/i.26){a.
x
261329910883437428257896643x A.x
247073478763191548160234722x A.x
(_1+/-i.26){x

Mi primera experiencia con J. La idea es simplemente usar el número canónico (lexicográfico) de la permutación requerida; desafortunadamente, esto requiere más caracteres que codificarlo. Pero si uno pudiera encontrar alguna expresión aritmética (usando poderes y demás) que produzca los números mágicos, podría acortarse.


261329910883437428257896643 tiene la factorización prima 7 * 601 * 991 * 213987797 * 292923318887 por lo que no hay poderes en este.
Jerry Jeremiah

3

Python, 90 caracteres unicode

#coding:u8
print u"扡摣晥桧橩汫湭灯牱瑳癵硷穹睱牥祴極灯獡晤桧歪穬捸扶浮祰杦牣慬敯極桤湴煳歪扸睭究祺睸當獴煲潰浮歬楪杨敦捤慢".encode("u16")[2:]

ejecutar en ideone - http://ideone.com/R2dlI o codepad - http://codepad.org/lp77NL9w


2
En realidad, solo tiene 52 "caracteres".
Peter Olson el

3

Javascript 139 121

nuevo:

q='qwertyuiopasdfghjklzxcvbnm'
a=q.split('').sort()
alert(a.join('')+q+'pyfgcrlaoeuidhtnsqjkxbmwvz'+a.reverse().join(''))

antiguo:

a=[]
a[26]='qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz'
for(i=0;i<26;i++)a[i]=a[52-i]=String.fromCharCode(i+65)
alert(a.join(''))

También podría tener 121 con:alert((a=(q='qwertyuiopasdfghjklzxcvbnm').split('').sort()).join('')+q+'pyfgcrlaoeuidhtnsqjkxbmwvz'+a.reverse().join(''))
WallyWest

2

Lua - 111 caracteres

Beats C y C ++! :-)

print'abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvzzyxwvutsrqponmlkjihgfedcba'

Versión "inteligente" en Lua

129 caracteres

q='qwertyuiopasdfghjklzxcvbnm'a={q:byte(1,-1)}table.sort(a)a=q.char(unpack(a))print(a,q,'pyfgcrlaoeuidhtnsqjkxbmwvz',a:reverse())

Espacio en blanco:

q='qwertyuiopasdfghjklzxcvbnm'
a={q:byte(1,-1)}
table.sort(a)
a=q.char(unpack(a))
print(a,q,'pyfgcrlaoeuidhtnsqjkxbmwvz',a:reverse())

2

C - 163135 caracteres

Esto no cumple con los requisitos, ya que cuenta con más de 104 caracteres, pero fue divertido de hacer. Quizás alguien tenga algunas sugerencias.

main(i){char a[105];strcpy(&a[26],"qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz");for(i=0;i<26;)a[i]=a[103-i]=i+++65;puts(a);}

Esto compila en GCC 4.5.1 (otros no probados). ¡Yay por omitir #incluye, tipos de retorno y declaraciones de variables! La codificación rígida hubiera resultado en un programa más corto, pero eso no es divertido.

Versión de espacios en blanco:

main(i) {                                                                                   
    char a[105];                                                                        
    strcpy(&a[26], "qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz");                 
    for(i=0;i<26;)                                                                          
        a[i]=a[103-i]=i+++65;                                                               
    puts(a);                                                                                
}

C - 124122 cojo

Aquí está la versión rígida codificada, y todavía no hace el corte.

main(){puts("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvzzyxwvutsrqponmlkjihgfedcba");}

Utilice en su puts()lugar printf en el segundo caso: 2 caracteres menos.
Alexander Gladysh

Y reemplazar whilecon puts(a);en el primer caso, soltar *p=a; - 138 caracteres en lugar de 163.
Alexander Gladysh

Sugerencias impresionantes! Me había olvidado por completo puts. Cambiado.
Casey

2

PHP 88 bytes

<?=$a=join(range(a,z)),~Žˆš‹†Š–žŒ›™˜—•”“…‡œ‰‘’†™˜œ“žšŠ–›—‹‘ŒŽ•”‡’ˆ‰…,strrev($a);

2

J - 69 char

'pyfgcrlaoeuidhtnsqjkxbmwvz'(,~|.)&(,\:~)'mnbvcxzlkjhgfdsapoiuytrewq'

Explicación:

  • (,\:~) y- Ordenar yen orden descendente ( \:~) y anexar ( ,) eso a y.

  • x (,~|.) y- Invierta ( |.) yy añádalo al frente de x.

  • x F&G y- Ejecutar (G y) F (G y), es decir, realizar Flos resultados de la aplicación Ga los argumentos.

Entonces, todos juntos, agregamos el alfabeto, hacia atrás, a las cadenas Dvorak y QWERTY inversa, luego invierte la QWERTY / alfabeto y la ponemos frente a la Dvorak / alfabeto.


2

Bash, 64

Llego muy tarde a la fiesta, pero tengo una solución de 64 personajes. El programa debe guardarse en el disco para funcionar

echo {a..z} $(sed 1d $0|base64) {z..a};exit
««·+¢¢–¬uø!ŽIsÅËÛžjr~+•ªº'a¶{*ŽL[›ó

Cómo funciona:

{a..z}y {z..a}se explican por sí mismos, pero básicamente eso solo imprime cada personaje en ese rango respectivo.

$(sed 1d $0|base64) emite el programa, ignora la primera línea y luego la pasa a través de un codificador base64 (como lo han hecho otros ejemplos).

La razón por la que esto es más corto que otros ejemplos similares ...

... es porque los {a..z}rangos son más cortos que las codificaciones base64, por lo que solo necesito codificar en base64 la mitad de la cadena. Y como estoy leyendo los datos binarios del archivo en lugar de almacenarlos en una cadena, no necesito escapar de ningún carácter en el código.

Cómo recrear este script:

Si el código no copia / pega correctamente desde Stack Exchange a su editor de texto, ejecute lo siguiente en su línea de comando (agnóstico de shell):

echo 'echo {a..z} $(sed 1d $0|base64) {z..a};exit' > alphabetgolf
echo 'qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz' | base64 -d >> alphabetgolf

Luego correr:

bash alphabetgolf

2

05AB1E , 25 bytes

AžW.•8t”a$äJÚ₁вƒüu¯Cê•AR»

Pruébalo en línea!

Explicación

A                          # Push alphabet                    
 žW                        # Push qwerty string
   .•8t”a$äJÚ₁вƒüu¯Cê•     # Push compressed dvorak string
                      AR   # Push reversed alphabet
                         » # Join entire stack with newlines

1

C ++

Es un poco triste cuando la forma más corta de hacer algo en un idioma es codificarlo.

#include <iostream>

int main()
{
 std::cout<<"abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvzzyxwvutsrqponmlkjihgfedcba";
}

No necesita dar salida a los avances de línea.
Lowjacker

@ Low: Doh! Olvidé eliminarlos cuando eliminé los saltos de línea y me di cuenta de que no los necesitaba. Gracias por señalar eso.
John

Esta es una solución muy obvia y supera el requisito de longitud máxima.
Peter Olson el

std::coutes más corto que eso using namespace std, y puedes saltarte void.
Alexander Gladysh

@ Alex: Gracias por señalar eso.
John

1

J (77)

(,|.@(26&{.))(,~/:~@(26&{.))'qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz'

Afeitado de 3 caracteres mediante el uso de una variable:

(,|.@a)(,~/:~@(a=.26&{.))'qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz'

Afeitado 2 personajes más mediante el uso de un enfoque de nivel de valor:

(|.a),~t,~a=./:~26{.t=.'qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz'

1

Haskell (95)

main=putStr$['a'..'z']++"qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz"++['z','y'..'a']

Perl (51)

No hay una regla que diga que no puedo.

use LWP::Simple;print get("http://bit.ly/fGkflf");

1
Vea la lista de lagunas estándar .
boboquack

1

Q (68)

.Q.a,"qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz",(|:).Q.a

Salidas:

"abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnmpyfg     
crlaoeuidhtnsqjkxbmwvzzyxwvutsrqponmlkjihgfedcba"

Intenté encontrar una mejora en la codificación rígida de los dos medios, pero no se me ocurrió ninguno.


1

K - 69 char

b,a,|b:a@<26#a:"qwertyuiopasdfghjklzxcvbnmpyfgcrlaeouidhtnsqjkxbmwvz"

Explicación:

  • 26#a:- Asigne los dos diseños de teclado ay luego tome los primeros 26 caracteres.

  • b:a@<- Ordenar ay asignar eso a b: <proporciona la permutación para un orden ascendente y @nos permite indexar apara ordenarlo.

  • b,a,|- Agregue en una fila b, luego a, luego el reverso ( |) de b.


1

Pyth, 57

G"qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz"VG

Alfabeto, cadena, alfabeto invertido. G es el alfabeto. La impresión es implícita.


1

Dyalog APL , 60 bytes

⎕A'QWERTYUIOPASDFGHJKLZXCVBNMPYFGCRLAOEUIDHTNSQJKXBMWVZ',⌽⎕A

Huellas dactilares:

  ABCDEFGHIJKLMNOPQRSTUVWXYZ  QWERTYUIOPASDFGHJKLZXCVBNMPYFGCRLAOEUIDHTNSQJKXBMWVZ ZYXWVUTSRQPONMLKJIHGFEDCBA

Que está permitido según OP:

La salida no distingue entre mayúsculas y minúsculas, y puede agregar u omitir nuevas líneas o espacios donde lo desee.


1

Gelatina, 36 bytes (no competitiva)

Øa;Øq;“pyfgcrlaoeuidhtnsqjkxbmwvz”;U

Pruébalo en línea!

Explicación:

Øa;Øq;“pyfgcrlaoeuidhtnsqjkxbmwvz”;U    |
Øa;                                     | alphabet
   Øq;                                  | list with all rows of the qwerty keyboard
      “pyfgcrlaoeuidhtnsqjkxbmwvz”;     | string
                                   U    | reverse

1

05AB1E , 60 59 bytes

AÂ"qwertyuiopasdfghjklzxcvbnm""pyfgcrlaoeuidhtnsqjkxbmwvz"»

Pruébalo en línea!

- empuja el alfabeto bifurcado.

"qwertyuiopasdfghjklzxcvbnm""pyfgcrlaoeuidhtnsqjkxbmwvz" - Empuja qwerty y drovak.

» - Impresiones de pila.

05AB1E , 57 bytes (si no te importa el azar \ n)

AÂ"qwertyuiopasdfghjklzxcvbnmpyfgcrlaoeuidhtnsqjkxbmwvz"»

Pruébalo en línea!


En el primer ejemplo, puede guardar un byte reemplazándolo ""con una nueva línea.
Neil A.
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.