Gerando o alfabeto em JavaScript

21

Tenho certeza de que não há uma maneira melhor de fazer isso, mas achei que não faria mal perguntar.

Estou cansado de digitar a='abcdefghijklmnopqrstuvwxyz'.

Idiomas legais têm Range('a'..'z')ou similar

O que podemos criar com o JS o mais curto possível?

for(i=97,a='';i<123;){a+=String.fromCharCode(i++)}

é mais do que apenas o alfabeto - mas garante que não estrago em algum lugar.

Espero que exista uma maneira desagradável de produzir az em menos de 50 caracteres.

Eu brinquei com i=97;Array(26).map(x=>String.fromChar....i++

mas sempre era muito mais longo quando entrei e depois dividi a matriz (26) para ser utilizável


Edit: Eu tenho que chegar até

[...Array(26)].reduce(a=>a+String.fromCharCode(i++),'',i=97)

60 bytes

Charlie Wynn
fonte
11
@muddyfish, LuisMendo: Este tópico é por meta.
Maçaneta
11
[...Array(26)].map((q,w)=>String.fromCharCode(w+97))tem 52 bytes e adicione outros 7 para o.join``
andlrc
Veja também: stackoverflow.com/questions/3895478/…
Digital Trauma
@ dev-null a = ''; i = 97; [... Array (26)]. map (b => a + = String.fromCharCode (i ++)) é 60, mas cuida da junção como você está fazendo a junção em 7 sem obter vírgulas no resultado?
Charlie Wynn
11
@CharlieWynn[...Array(26)].map((q,w)=>String.fromCharCode(w+97)).join``
andlrc

Respostas:

12

Alternativa ao String.fromCharCode

... se você estiver satisfeito com um alfabeto apenas em minúsculas.

for(i=9,a='';++i<36;)a+=i.toString(36) // 38, cannot be used in an expression
[...Array(26)].map(_=>(++i).toString(36),i=9).join`` // 52 directly returnig the string desired
[...Array(26)].map(_=>a+=(++i).toString(36),a='',i=9) // 53 assign to a variable
(i=9,[for(_ of Array(26))(++i).toString(36)].join``) // 52 ES7 direct return
i=9,a='',[for(_ of Array(26))a+=(++i).toString(36)] // 51 ES7 assign to a variable
edc65
fonte
11
Oh caramba, isso é inteligente. Então está começando com 10, convertendo para a base 36 e imprimindo? tão az!
10136 Charlie Wynn
São esses argumentos a = '' e i = 9 da chamada de função do mapa? Verifiquei Array.prototype.map () no mdn e não parece que o mapa suporte esses argumentos ..
Jay Somedon 22/01
@ JaySomedon esses são argumentos para a chamada de função de mapa, de certa forma, as funções Javascript normalmente não se importam e descartam parâmetros que eles não esperam. Então, eu inicializo uma variável que eu preciso, enquanto adicionava um parâmetro que não é útil para a função chamada
edc65
@JaySomedon veja também esta resposta e comentários relacionados codegolf.stackexchange.com/a/2684/21348
edc65
@ edc65 aha eu vejo! Isso é legal! Então aqui, quando o javascript avalia argumentos como i = 9 no mapa (), na verdade ele cria uma variável global e atribui 9 a isso?
Jay Somedon 23/01
11

Nota: Todas essas técnicas atribuem a sequência do alfabeto à variável a.


Estou 99% certo de que a maneira mais curta de conseguir isso em JavaScript é de fato:

a="abcdefghijklmnopqrstuvwxyz" // 30 bytes

Mas existem vários outros métodos interessantes. Você pode usar a compactação de string:

a=btoa`i·?yø!?9%?z)ª»-ºü1`+'yz' // 31 bytes; each ? represents an unprintable

Você pode obter a sequência compactada de atob`abcdefghijklmnopqrstuvwx`. Ele 'yz'deve ser adicionado manualmente, porque se você compactar a sequência inteira, enquanto o resultado for de apenas 27 bytes, será exibido como abcdefghijklmnopqrstuvwxyw==.

Acredito que a maneira mais curta de fazer isso programaticamente também é o método que você sugeriu:

for(i=97,a='';i<123;)a+=String.fromCharCode(i++) // 48 bytes

Você pode fazer isso com os recursos do ES6 ( cadeias de modelo`` , operador de propagação... ) se desejar:

a=[...Array(26)].map(_=>String.fromCharCode(i++),i=97).join`` // 61 bytes
a=[...Array(26)].map((_,i)=>String.fromCharCode(i+97)).join`` // also 61 bytes
a=[...Array(i=26)].map(_=>String.fromCharCode(++i+70)).join`` // again, 61 bytes

Você pode fazer um melhor com uma variável em vez de .join``:

[...Array(26)].map(_=>a+=String.fromCharCode(i++),i=97,a='') // all 60 bytes
[...Array(26)].map((_,i)=>a+=String.fromCharCode(i+97),a='')
[...Array(i=26)].map(_=>a+=String.fromCharCode(++i+70),a='')

Ou ES7 com compreensões de matriz , que é outro byte mais curto:

a=[for(_ of Array(i=26))String.fromCharCode(++i+70)].join`` // 59 bytes

Criar a variável antecipadamente salva outro byte:

a='',[for(_ of Array(i=26))a+=String.fromCharCode(++i+70)] // 58 bytes

Além disso, String.fromCharCodeaceita vários argumentos e os juntará automaticamente. Portanto, podemos jogar cada versão do ES6 com até 57 bytes:

a=String.fromCharCode(...[...Array(26)].map(_=>i++,i=97)) // all 57 bytes
a=String.fromCharCode(...[...Array(26)].map((_,i)=>i+97))
a=String.fromCharCode(...[...Array(i=26)].map(_=>++i+70))

E o ES7 diminuiu para 55:

a=String.fromCharCode(...[for(_ of Array(i=26))++i+70]) // 55 bytes

Se você quiser saber mais sobre os campos de golfe, confira este conjunto de dicas . Há também uma sobre as compreensões de matriz do ES7 .

EDIT: Como o edc65 apontou, a maioria deles fica mais curta usando, em i.toString(36)vez de String.fromCharCode(i):

for(i=9,a='';++i<36;)a+=i.toString(36) // 38 bytes
a=[...Array(26)].map(_=>(++i).toString(36),i=9).join`` // 54 bytes
[...Array(26)].map(_=>a+=(++i).toString(36),i=9,a='') // 53 bytes
i=9,a=[for(_ of Array(26))(++i).toString(36)].join`` // 52 bytes
i=9,a='',[for(_ of Array(26))a+=(++i).toString(36)] // 51 bytes

Eu acredito que este é o menor possível que pode ser chamado como um valor de retorno de função:

eval("for(i=9,a='';++i<36;)a+=i.toString(36)") // 46 bytes

É três bytes menor que o retorno manual de uma função:

x=>eval("for(i=9,a='';++i<36;)a+=i.toString(36)") // 49 bytes
x=>{for(i=9,a='';++i<36;)a+=i.toString(36);return a} // 52 bytes

Claro, x=>"abcdefghijklmnopqrstuvwxyz"ainda supera tudo o resto.

ETHproductions
fonte
Eu realmente gosto de onde isso vai dar - só queria poder ES7 em cromo :(
Charlie Wynn
2
@CharlieWynn Sim, é uma pena que nem todos os navegadores suportem todos os recursos mais recentes. Mas, afinal, o Chrome não foi construída em um dia ...;)
ETHproductions
A maioria dessas soluções pode ser reduzida usando .toString em vez de String, .fromCharCode. Veja minha resposta
edc65
11
@CharlieWynn Acho que o Chrome Beta agora suporta todo o ES7 e todo o ES6, exceto os módulos e a otimização da chamada final.
gcampbell
Aqui é a 42-Byter que pode ser chamado como um valor de retorno de função: (f=(i=9)=>++i<36?i.toString(36)+f(i):'')()
Rick Hitchcock
7

Aqui está outra abordagem, uma expressão ES6 de 51 bytes:

String.fromCharCode(...Array(123).keys()).slice(97)

50 bytes em maiúsculas, é claro.

Neil
fonte
Para maiúsculas: String.fromCharCode (... Array (91) .keys ()). Slice (65)
jpoppe
1

36 bytes, usando um truque que acabei de aprender (a partir deste post: /codegolf//a/176496/64538 ):

for(i=9;++i<36;)name+=i.toString(36)

window.name é uma sequência vazia por padrão.

Obviamente, isso é ainda menos prático que a solução de 38 bytes, pois usa um nome de variável mais longo.

12Me21
fonte
1

Usando o que pode ou não ser definido no escopo global

39 bytes para que as propriedades do objeto correspondam à matriz a-z

a=`${Object.keys(top)}`.match(/[a-z]/g)

48 bytes para um não classificado Set

a=new Set(`${Object.keys(top)}`.match(/[a-z]/g))

55 bytes para uma classificação Set

a=new Set(`${Object.keys(top)}`.match(/[a-z]/g).sort())

67 bytes para uma sequência classificada

a=[...new Set(`${Object.keys(top)}`.match(/[a-z]/g).sort())].join``
guest271314
fonte