¡Analiza mi esperanto!


21

El famoso lenguaje construido Esperanto usa el alfabeto latino (principalmente, vea la página de Wikipedia vinculada para más detalles). Sin embargo, hay algunos caracteres con acentos: ĉ, ĝ, ĥ, ĵ, ŝ y ŭ . (C-circumflex, g-circumflex, h-circumflex, j-circumflex, s-circumflex y u- breve .) Naturalmente, estos caracteres son muy difíciles de escribir. Incluso para esta pregunta, tuve que buscar en el selector Unicode los caracteres. Debido a esto, se ha desarrollado una convención que usa la letra "x" para uso electrónico. Por ejemplo, "cxu" se usa para "ĉu". (Nota: la letra "x" no se usa normalmente en el alfabeto esperanto ".

Sin embargo, ¡soy un purista del lenguaje! ¡Esta * cita aérea * x tonterías me está matando! ¡Necesito un programa para solucionar esto, preferiblemente lo más corto posible para poder escribirlo en mi terminal lo más rápido posible!

Reto

Tu misión es tomar una cadena de esperanto usando la convención x y convertirla en esperanto real.

En efecto, tienes que mapear:

cx: ĉ
gx: ĝ
hx: ĥ
jx: ĵ
sx: ŝ
ux: ŭ
Cx: Ĉ
Gx: Ĝ
Hx: Ĥ
Jx: Ĵ
Sx: Ŝ
Ux: Ŭ

Todos los demás caracteres ASCII imprimibles deben aceptarse y no modificarse. Unicode sería bueno, pero no necesario.

La entrada y salida pueden estar en cualquier formato razonable para su idioma. ¡Buena suerte!

Casos de prueba

"input" : "output"
_____________
"gxi estas varma" : "ĝi estas varma"
"Cxu sxi sxatas katojn aux hundojn?" : "Ĉu ŝi ŝatas katojn aŭ hundojn?"
"Uxcxsxabcd(hxSx)efg{};" : "Ŭĉŝabcd(ĥŜ)efg{};"
"qwertyuiop" : "qwertyuiop"
" " : " "
"" : ""
"x" : "x"
"xc" : "xc"
"xcx" : "xĉ"
"cxx" : "ĉx"

Tanteo

Este es el . Las respuestas se puntúan por el bytecount más pequeño en la codificación predeterminada del idioma.

Aquí hay un fragmento de pila para generar una tabla de clasificación regular y una descripción general de los ganadores por idioma.

Para asegurarse de que su respuesta se muestre, comience con un título, utilizando la siguiente plantilla de Markdown:

# Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

# Perl, 43 + 2 (-p flag) = 45 bytes

También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento de la tabla de clasificación:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

¡Buena suerte, diviértete y no dudes en sugerir mejoras!

Aclaraciones:

  • Solo necesita preocuparse por los caracteres ASCII imprimibles .

  • Solo necesita generar un carácter que se vea como el resultado correcto. Sí, esto significa que puede agregar el acento al carácter estándar.


ASCII aquí significa 20-7E caracteres imprimibles, 00-7F, ¿o qué?
user202729

Todos los imprimibles.
OldBunny2800

Nota: agregué una aclaración de que puede usar la letra y el acento modificador.
OldBunny2800

55
La combinación de circunflejo está en 0302 ̂, y la combinación de breve está en 0306 ̆.
user202729

^ Cada uno toma 2 bytes en UTF8 como recuento de TIO .
usuario202729

Respuestas:


9

QuadR , 65 bytes

.x
3::⍵M'ĉĝĥĵŝŭĈĜĤĴŜŬ'['cghjsuCGHJSU'⍳⊃⍵M]

Pruébalo en línea!

.x reemplace cualquier carácter seguido de "x" con

3::⍵M tras el error de indexación, devuelva la coincidencia sin modificar
 ahora intente:
'ĉĝĥĵŝŭĈĜĤĴŜŬ'[... ] indexar en esta cadena con
  ⍵M el  índice de la
   primera letra de la coincidencia  en esta cadena
  
  'cghjsuCGHJSU'

Esto es equivalente a la función tácita Dyalog APL:

'.x'R{3::⍵.Match'ĉĝĥĵŝŭĈĜĤĴŜŬ'['cghjsuCGHJSU'⍳⊃⍵.Match]}

¡Buena respuesta! +1
OldBunny2800

No estoy seguro de cómo se cuentan los bytes aquí. ¿No es el uso directo de ⎕R más corto? ('cghjsuCGHJSU',¨'x')⎕r(,¨'ĉĝĥĵŝŭĈĜĤĴŜŬ')
ngn

@ngn Lo es, pero mi batería se agotó antes de que tuviera la oportunidad de publicar eso.
Adám

6

Retina , 27 bytes

iT`x`̂`[cghjs]x
iT`x`̆`ux

Pruébalo en línea!

Este programa está compuesto por dos transliteraciones. Debido a que tiene caracteres combinados en el código, esto no se procesa demasiado bien, la primera línea debería ser similar a iT`x`^`[cghjs]x, donde ^representa el carácter combinatorio acento circunflejo. Lo que esto está diciendo es que debería Transliterate ( icaso de gnoring) todos los xs en la entrada en a ^, siempre que estén siguiendo cualquier letra [cghjs].


Nota: TIO mide incorrectamente este código como 25 bytes. En realidad, este programa Retina usa codificación UTF-8 (otros programas pueden usar UTF-32 o ISO 8859-1) y los dos caracteres combinados presentan un costo de 2 bytes cada uno.


5

C,  173  154 bytes

¡Gracias a @Colera Su por guardar 17 bytes!

p,c,i;f(char*s){for(char*l="cghjsuCGHJSU";p=*s;~c&&putchar(p))for(c=*++s,i=0;c=='x'&&l[i];++i)l[i]-p||write(1,"ĉĝĥĵŝŭĈĜĤĴŜŬ"+i*2,2,c=-1,++s);}

Pruébalo en línea!

Explicación:

p,c,i;
f(char*s)
{
    // The outer loop and an array of characters that are modified by a trailing 'x'.
    // The array/string is used for getting the index for the accented character later.
    for (char*l="cghjsuCGHJSU";

                                // Store the current character of the input string in 'p'.
                                // If it is '\0', the loop terminates.
                                p=*s;

                                      // The last statement in the loop.
                                      // If 'c==-1', it outputs the char stored in 'p'. 
                                      ~c&&putchar(p))

        // Store the character following 'p' in 'c' and increment the string pointer.
        for(c=*++s, i=0;

                        // If 'c' is not the letter 'x', the inner loop terminates
                        // immediately. Otherwise it loops through the characters of
                        // string 'l'.
                        c=='x'&&l[i]; ++i)

            // If the character stored in 'p' is found inside the string 'l'...
            l[i]-p ||

                      // ...then print the accented character corresponding to 'p'.
                      // 'i' is the index of 'p' in 'l', and, because the characters
                      // with accents are two bytes each, the index is multiplied by 2.
                      write(1,"ĉĝĥĵŝŭĈĜĤĴŜŬ"+i*2,2,

                      // Finally set 'c' to -1 so that the non-accented character doesn't
                      // get printed too, and increment the string pointer so that the
                      // letter 'x' doesn't get printed either.
                                                    c=-1, ++s);
}

¡Agradable! ¿Puedo tener una explicación por favor?
OldBunny2800

Probablemente puede usar byte nulo literal en lugar de \0?
usuario202729

(pero eso desafortunadamente no funciona en TIO)
user202729

Puede usar write(1,"..."+i*2,2)para guardar 17 bytes. Pruébalo en línea!
Colera Su

5

Python 3 , 81 bytes

lambda s,T="cĉgĝhĥjĵsŝuŭ":eval("s"+".replace('%sx',%r)"*12%(*T+T.upper(),))

Pruébalo en línea!

Genera y evalúa la cadena:

s.replace('cx','ĉ').replace('gx','ĝ').replace('hx','ĥ').replace('jx','ĵ').replace('sx','ŝ').replace('ux','ŭ').replace('Cx','Ĉ').replace('Gx','Ĝ').replace('Hx','Ĥ').replace('Jx','Ĵ').replace('Sx','Ŝ').replace('Ux','Ŭ')

Erik el Outgolfer salvó un byte.


@EriktheOutgolfer Buen día, gracias!
xnor

3

/// , 75 bytes

/,/\/\///>/x\,/c>ĉ,g>ĝ,h>ĥ,j>ĵ,s>ŝ,u>ŭ,C>Ĉ,G>Ĝ,H>Ĥ,J>Ĵ,S>Ŝ,U>Ŭ/

Nota: Debido a que la solicitud OP debe procesar todos los caracteres imprimibles, mis "caracteres especiales" elegidos no deben ser imprimibles. Así que elegí tab y nueva línea en lugar de, lo que no cambia mi bytecount o la funcionalidad del código. El código se vería así:

/
/\/\/// /x\
/c  ĉ
g   ĝ
h   ĥ
j   ĵ
s   ŝ
u   ŭ
C   Ĉ
G   Ĝ
H   Ĥ
J   Ĵ
S   Ŝ
U   Ŭ/

Sin embargo, eso requiere que la entrada no debe contener tabulaciones o nuevas líneas.

Pruébalo en línea!

Debido a ///que no puede tomar entrada, debe poner la entrada después del código.

Muy claro. Supongo que no puede ser más corto porque ///necesita un manejo especial de cada personaje.

Explicación:

/,/\/\//       Replace all `,` in the code by `//`
               (two slashes are represented as two backslash-ed slashes)
/>/x\,         (in original code) becomes
/>/x\//        (because `,` is replaced by `//`) - replace all occurence of 
               `>` by `x/`.
/cx/ĉ//gx/ĝ//hx/ĥ//jx/ĵ//sx/ŝ//ux/ŭ//Cx/Ĉ//Gx/Ĝ//Hx/Ĥ//Jx/Ĵ//Sx/Ŝ//Ux/Ŭ/
               ^ The remaining part of the code should look like this.
               Straightforward replacement.

3

Python 3 , 95 bytes

f=lambda x,v="cĉgĝhĥjĵsŝuŭCĈGĜHĤJĴSŜUŬ":v and f(x.replace(v[0]+"x",v[1]),v[2:])or x

Pruébalo en línea!

-10 bytes gracias a WhatToDo
-1 byte gracias a Colera Su



@ user507295 oh idea inteligente. ¡Gracias!
HyperNeutrino

Use y / o truco para guardar un byte: ¡ Pruébelo en línea!
Colera Su

@ ColeraSu oh genial, gracias. no estoy seguro de por qué ese truco desapareció D:
HyperNeutrino

@HyperNeutrino Porque no sabía sobre ese truco. ¡Lo siento!
WhatToDo

2

Retina , 55 bytes

iT`CG\HJSUcg\hjsux`ĈĜĤĴŜŬĉĝĥĵŝŭ_`[cghjsux]x

Pruébalo en línea! Enfoque sin combinación. Los bytes podrían guardarse si no fuera por los xcasos de prueba independientes .



1

JavaScript (ES6), 92 bytes

s=>[..."cghjsuCGHJSU"].reduce((a,v,i)=>a.split(v+"x").join("ĉĝĥĵŝŭĈĜĤĴŜŬ"[i]),s)

Pruébalo en línea!

Se usó el método de unión dividida recomendado aquí para reducir el conteo de bytes porque el new RegExp(/*blah*/)constructor tomó demasiados bytes.

Comparación:

Original: a.replace(new RegExp(v+"x", "g"), "ĉĝĥĵŝŭĈĜĤĴŜŬ"[i])
New     : a.split(v+"x").join("ĉĝĥĵŝŭĈĜĤĴŜŬ"[i])

Más corto, combinando enfoque de acento (63 bytes), pero con algunos artefactos visibles.

s=>s.replace(/([cghjs])x/gi," ̂$1").replace(/(u)x/gi," ̌$1");

Nota al pie: Estoy reclamando mi respuesta 92 bytes porque la solución de 63 bytes tiene artefactos que pueden afectar la salida.


1

APL (Dyalog Unicode) , 57 bytes

Función tácita anónima. Usos:

  1. Función de prefijo a cadena. Esto translitera la cadena.

  2. Función de prefijo a la lista de cadenas. Esto translitera las cuerdas.

  3. Función de infijo con número de enlace del archivo de entrada como argumento derecho y número de enlace del archivo de salida como argumento izquierdo. Esto llena el archivo de salida con el contenido transliterado del archivo de entrada.

('cghjsuCGHJSU',¨'x')⎕R(,¨'ĉĝĥĵŝŭĈĜĤĴŜŬ')

(... )⎕R(... ) PCRE R eplace

'cghjsuCGHJSU' estas cartas

,¨'x' cada uno seguido de una x

 … con…

,¨'ĉĝĥĵŝŭĈĜĤĴŜŬ' cada una de estas letras como cadenas

Pruébalo en línea!


1

J , 64 63 bytes

rplc((_2]\'ĉĝĥĵŝŭĈĜĤĴŜŬ');~"1'cghjsuCGHJSU',.'x')"0

Cómo funciona:

Con _2]\reorganizo la cadena 'ĉĝĥĵŝŭĈĜĤĴŜŬ' en una columna de 12 filas para que se ajuste a la forma de la otra cadena.

,. agrega 'x' a cada carácter de la cadena 'cghjsuCGHJSU' y forma una matriz de 12 filas por 2 columnas

;~"1' hace una lista de los pares en caja de los anteriores, "1 - rango 1 - se aplica a cada fila.

┌──┬──┐
│cx│ĉ │
├──┼──┤
│gx│ĝ │
├──┼──┤
│hx│ĥ │
├──┼──┤
│jx│ĵ │
├──┼──┤
│sx│ŝ │
├──┼──┤
│ux│ŭ │
├──┼──┤
│Cx│Ĉ │
├──┼──┤
│Gx│Ĝ │
├──┼──┤
│Hx│Ĥ │
├──┼──┤
│Jx│Ĵ │
├──┼──┤
│Sx│Ŝ │
├──┼──┤
│Ux│Ŭ │
└──┴──┘

rplc usa estos elementos en caja para reemplazar cada aparición del elemento en caja izquierda de un par con el derecho.

Pruébalo en línea!


1

Befunge , 2x48 +1 = 99 bytes

>~:1+!#@_:"x"-v>$ 11p0"cghjsuCGHJSU"1\ >\31p11g-v
^ # #, : ++$\ _^#1"x"0*4!-"u"g11*"ʊ"!\_^#!:\*g13<

Pruébelo (TIO es muy extraño sobre Befunge y no pude conseguir que ninguna de mis soluciones funcionara)

Cómo funciona

>~:1+!@_

Obtiene información y comprueba si es el final. Fin del programa si es así.

          "x"-v>
^ # #, : ++$\ _^

Comprueba si el personaje es una "x". Si no, conserve una copia del personaje e imprímalo.

               >$ 11p0"cghjsuCGHJSU"1\

Almacene el último personaje en (1,1). Pone a todos los personajes para verificar en la pila.

                                       >\31p11g-v
                                      _^#!:\*g13<

Compare el último carácter con todos los valores en la pila.

                 1"x"0*4!-"u"g11*"ʊ"!\

Multiplique el cheque (0 o 1) por ʊ (valor unicode 650). Comprueba si el personaje era au (para el breve) y agrega 4 a la pila si es así. Finalmente, agregue el valor ascii de x (100) también. El total se suma al acento correcto si es necesario o simplemente una "x" si no.

>~:1+!#@_  
^ # #, : ++$\ _^#

Agregue todos los valores en la pila, imprímalo y mantenga un duplicado. Regrese para la siguiente entrada.


1

R , 75 70 bytes

function(s)gsub('([cghjs])x','\\1\U302',gsub('(u)x','\\1\U306',s,T),T)

Pruébalo en línea!

-5 bytes gracias a Giuseppe

Explicación

  • gsub('(u)x','\\1\U306',s,T): reemplace en scada aparición de una "u" mayúscula o minúscula (mediante el uso ignore.case=TRUEdel cuarto argumento T) seguido de una "x", la "u" seguida de unicode para un breve
  • gsub('([cghjs])x','\\1\U302',gsub('(u)x','\\1\U306',s,T),T): tome el resultado de eso y reemplace cada aparición de mayúsculas o minúsculas ( ignore.case=TRUEmediante el cuarto argumento T) "c", "g", "h", "j" o "s" seguido de una "x" con la letra seguida del unicode para un circunflejo

usar el orden de argumentos en lugar de nombrar ahorra 3 bytes, y otros dos se deshacen del cero inicial \U0302y \U0306: ¡ Pruébelo en línea!
Giuseppe

@Giuseppe - gran idea, gracias!
Duckmayr

1

QuadR , 25 bytes

Edición combinada de diacríticos.

ux
([cghjs])x
 ̆&
 ̂\1

i bandera

Pruébalo en línea!

Reemplazar…

(u)x         u followed by x and
([cghjs])x   any of these letters followed by x 
 ̆\1          by a breve followed by the first group (the u) and
 ̂\1          a circumflex followed by the first group (the letter)

entre mayúsculas i nsensitively

Equivalente al siguiente código Dyalog APL:

'(u)x' '([cghjs])x'R' ̆\1' ' ̂\1'

¿Por qué es esto 28 y no 24 bytes?
Erik the Outgolfer

@EriktheOutgolfer El contador SBCS de TIO me confundió. Fijo. Gracias. Espera, ¿eso significa que gano?
Adám

Eh, ahora parece que son 27 bytes (copiados de TIO), pero 24 bytes cuando se copian desde aquí. ¿Qué es la codificación de QuadR y cuál es la correcta?
Erik the Outgolfer

@EriktheOutgolfer Ambos enlaces informan 24 en mi FFQ / Win10. QuadR usa Dyalog Classic o cualquier Unicode.
Adám

¿Entonces son 24 bytes o qué?
Erik the Outgolfer

1

C, 145 144 bytes

Otro enfoque de C. Regrese sobrescribiendo la entrada, usando el hecho de que circunflex / breve son 2 bytes.

-1 bytes gracias a Steadybox .

i,t;f(char*s){for(t=1;*s;s++)if(*s^'x')for(i=12,t=1;i--;)t="cghjsuCGHJSU"[i]-*s?t:i*2;else t^1&&memcpy(s-1,"ĉĝĥĵŝŭĈĜĤĴŜŬ"+t,2),t=1;}

Pruébalo en línea!


1
Usar en t^1&&memcpy(s-1,"ĉĝĥĵŝŭĈĜĤĴŜŬ"+t,2),t=1;lugar de t^1?memcpy(s-1,"ĉĝĥĵŝŭĈĜĤĴŜŬ"+t,2),t=1:0;guardar un byte. Pruébalo en línea!
Steadybox

1

Mathematica, 81 bytes o 57 bytes

StringReplace[RemoveDiacritics@#<>"x"->#&/@Characters@"ĉĝĥĵŝŭĈĜĤĴŜŬ"]

Aplica una regla de reemplazo donde la letra sin el sombrero junto con una "x" se reemplaza por la letra.

Aquí hay una alternativa usando el carácter de acentos agregado: StringReplace[{"ux"->"ŭ","Ux"->"Ŭ",c_~~"x":>c<>"̂"}]


1

Perl 5 , 49 + 2 ( -p -C) = 61 51 bytes

s/[CGHJScghjs]\Kx/\x{0302}/g;s/[Uu]\Kx/\x{0306}/g

Pruébalo en línea!

Guardado 10 bytes gracias a Nahuel Fouilleul


podría ahorrar 7 bytes:s/[CGHJScghjs]\Kx/\x{0302}/g;s/[Uu]\Kx/\x{0306}/g
Nahuel Fouilleul

parece que también funciona solo con -Cy sin -Cadvertencia ( Wide character in print)
Nahuel Fouilleul

1
de perlrun-C on its own (not followed by any number or option list), or the empty string "" for the PERL_UNICODE environment variable, has the same effect as -CSDL.
Nahuel Fouilleul

0

CJam , 51 bytes

q"ĉĝĥĵŝŭĈĜĤĴŜŬ""cghjsuCGHJSU".{'x+@\/*}

Pruébalo en línea!

Explicación:

q                   Read input
"ĉĝĥĵŝŭĈĜĤĴŜŬ"      String literal
"cghjsuCGHJSU"      Another string literal
.{                  Iterate over the strings in parallel
  'x+                 Add an 'x to the normal character
  @                   Rotate to bring the input to the top of stack
  \                   Swap to bring the "cx" to the top
  /                   Split the input on instances of "cx"
  *                   Join the input on instances of the accented character
}

¿Esto es realmente 39 bytes? Cuento 39 caracteres y no creo que CJam tenga una codificación especial.
user202729

@ user202729 Modificado (TIO contó los bytes como caracteres por alguna razón)
Esolanging Fruit el

Porque TIO cree que todos los idiomas de golf tienen una página de códigos de caracteres especiales, y no se molesta en verificar si todos los caracteres están en la página de códigos correcta.
user202729

0

sed, 108 bytes

s/cx/ĉ/g
s/gx/ĝ/g
s/hx/ĥ/g
s/jx/ĵ/g
s/sx/ŝ/g
s/ux/ŭ/g
s/Cx/Ĉ/g
s/Gx/Ĝ/g
s/Hx/Ĥ/g
s/Jx/Ĵ/g
s/Sx/Ŝ/g
s/Ux/Ŭ/g

Se debe formatear el código como código por `...`o <pre><code>...</code></pre>o 4 guiones.
usuario202729

@ user202729 Obviamente lo sabía. Estaba enviando desde mi teléfono Android, así que no lo formateé correctamente.
iBug

2
Parece que tiene 119 bytes de longitud.
Erik the Outgolfer

0

PowerShell, 58 bytes

Tiene 54 caracteres y guardarlo en PowerShell ISE lo convierte en UTF-8 + BOM para 58 bytes. No se procesa tan bien en un navegador:

$args-replace'(?<=u)x','̆'-replace'(?<=[cghjs])x','̂'

regex reemplaza la x con la combinación de caracteres Unicode del comentario de @ user202729.

p.ej

PS C:\> .\eo.ps1 "Cxu vi sxatas la cxapelliterojn? Mi ankaux."
Ĉu vi ŝatas la ĉapelliterojn? Mi ankaŭ.

0

Clojure, 126115 bytes

-11 bytes cambiando el mapa de reemplazo a una partición de una cadena.

#(reduce(fn[a[f r]](clojure.string/replace a(str f\x)(str r)))%(partition 2"cĉgĝhĥjĵsŝuŭCĈGĜHĤJĴSŜUŬ")) 

Una reducción sobre un mapa de reemplazos a buscar y con qué reemplazarlos.

Todavía estoy trabajando en una forma de comprimir el mapa de reemplazo.

(defn translate [^String esperanto]
  (reduce (fn [acc [f r]] (clojure.string/replace
                            acc ; Replace the translation so far by
                            (str f \x) ; adding a x after each character, search for it in the string,
                            (str r))) ; and replace it with a stringified accented char

          esperanto ; Before the reduction happens, the accumulator is the original string

          ; A list of [char-to-find what-to-replace-with] pairs
          (partition 2"cĉgĝhĥjĵsŝuŭCĈGĜHĤJĴSŜUŬ")))))


0

Scala , 110 bytes

Solución aburrida de expresiones regulares:

def?(s:String)="(.)x".r.replaceAllIn(s,m=>m.group(0)(0)+(if(m.group(0)(0).toUpper=='U')"\u0306"else"\u0302"))

Antigua solución scala (116 bytes)

def?(s:String)=s.foldLeft("")((r,c)=>if(c=='x')r.init+r.last+(if(r.last.toUpper=='U')"\u0306"else"\u0302")else r+c)

Sin golf

def?(s:String)=
  s.foldLeft("")((r,c)=>  // 'Fold' string with empty string as first result
    if(c=='x')            // If current character is x
      r.init+             // Take the every character from result but the last
        r.last+           // The last character from result and add
          (if(r.last.toUpper=='U')
            "\u0306"      // combining breve if 'u' or 'U'
          else"\u0302")   // combining circumflex in any other case
 else r+c                 // Otherwise return result + character
)

0

JavaScript, 35 caracteres, 36 bytes

s=>s.replace(/([cghjsu])x/gi,"$1̂")

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.