Dicas para jogar golfe em Japt


18

Agora que sou completamente viciado em Code Golf, provavelmente já é hora de tentar entender alguns idiomas do golfe.

Dado que eu jogo quase exclusivamente em JavaScript, o Japt parece ser a linguagem lógica para começar. Vou mergulhar na documentação na próxima oportunidade que tiver, mas, enquanto isso, por favor, poste as dicas que você tem para o Japt nas respostas abaixo.

Como eu sou iniciante em japonês e nos idiomas de golfe em geral, se você pudesse "traduzir" suas dicas para JavaScript, sempre que possível, isso seria uma grande ajuda para me ajudar a entender as coisas.


Obrigado por postar isso. Eu estava adiando isso porque gostaria de redesenhar Japt em algum momento, mas isso não vai acontecer tão cedo, e provavelmente não vai atrapalhar muitas dicas de qualquer maneira. Dica para mim: escreva um tutorial: P
ETHproductions

Não se esqueça de visitar a sala de bate-papo do Japt :)
Oliver

Respostas:


11

Passando do JavaScript para o Japt

Como você deve saber, o Japt é simplesmente uma versão reduzida e estendida do JavaScript. Criei o Japt porque estava cansado de nomes de propriedades longos, como String.fromCharCode(x)e Math.floor(x), e o tédio de fazer coisas como criar um intervalo. Aqui está o mínimo que você precisa saber quando passa do JavaScript para o Japt:

  • Japt é uma língua transpilada ; O código Japt é transpilado para JavaScript e, em seguida, é executado como JS. (Eu acho que você poderia dizer compilado , mas transpilar soa mais moderno. Isenção de responsabilidade: não sei absolutamente nada sobre ser moderno)
  • Todas as entradas são programas completos por padrão. A entrada é analisado de forma implícita, e os primeiros seis entradas são colocados em variáveis U, V, W, X, Y, e Z; a matriz completa é armazenada em N. O resultado da última expressão é impresso automaticamente.
  • Todas as letras maiúsculas são variáveis ​​e permanecem as mesmas quando transpiladas. A maioria possui valores predefinidos, que podem ser encontrados na seção "Variáveis" dos documentos Japt (no intérprete ).
  • Todas as letras minúsculas são funções ou métodos de protótipo . Japt adiciona os métodos a- z(e à- ÿ) em números, seqüências de caracteres e matrizes. Quando você usa uma dessas letras, Japt preenche o .e (; Ucin Japt é equivalente a U.c(JavaScript, o que pode significar ceil, charCodeAt ou concat, dependendo do tipo de U. É daí que vem a maior parte do poder de Japt; você pode encontrar listas completas desses métodos nas seções "_____ funções" dos documentos Japt (no intérprete ).
  • Um espaço representa )e )representa )). Isso porque quando eu projetei o Japt, eu queria salvar o máximo de bytes possível, e foi assim que pensei em fazer isso. (Embora Us w npareça melhor do que Us)w)n), IMHO.)
  • Uma função é denotada como ABC{...}, onde ABCpode ser qualquer sequência de variáveis. As funções funcionam em grande parte como no JS, a principal diferença é que a última expressão é retornada automaticamente (em vez de ter que usar returnou imaginar parênteses do ES6).
  • 'denota uma única cadeia de caracteres (ou seja, 'aé igual a "a") e #pega o próximo código de caractere e se torna esse número ( #eé o mesmo que 101).
  • Qualquer coisa entre cifrões $permanece a mesma durante o processo de transpilação. Você pode usar isso para implementar forloops, por exemplo, já que o Japt não os possui, mas eu sugeriria o uso de outros métodos (como mem strings e matrizes ou oem números).
  • A maioria dos outros caracteres comumente usados em JS - "", 0-9, (, +, =, etc. - permanecer o mesmo quando transpiled (em sua maior parte, de qualquer maneira).

E é tudo o que você precisa saber para escrever o código japonês básico. Atingir a potência máxima do golfe em Japt requer mais conhecimento, mas isso pode ser encontrado em outras respostas.


Aqui está um exemplo básico. Digamos que você queira pegar uma sequência de caracteres ASCII e substituí-los por seu código de caracteres hexadecimal. Veja como você pode fazer isso em JavaScript:

U.split("").map(x=>x.charCodeAt(0).toString(16)).join("")

Agora converter para Japt. .split("")em JS é equivalente a q""em Japt, ou até mais curto, apenas q. .join("")também é justo q, a diferença é que o objeto é uma matriz em vez de uma string. .map(é m, .charCodeAt(é ce .toString(é s. Portanto, nosso código Japt pode se parecer com:

Uq mX{Xc0 s16} q 

No Japt, no entanto, mfunciona tanto em strings quanto em matrizes, para que possamos remover os dois qs:

UmX{Xc0 s16}

Teste online! Como você pode ver na caixa "Código JS", isso transpila diretamente para:

U.m(function(X){return X.c(0).s(16)})

À medida que aprende a trabalhar com o Japt, você fica cada vez menos focado na conversão para frente e para trás do JavaScript e pode codificar no Japt como seu próprio idioma. Aqui está uma explicação deixando de fora a parte do JavaScript completamente:

UmX{Xc0 s16}
               // Implicit: U = input string
UmX{       }   // Take U, and replace each character X with the result of this function:
    Xc0        //   Take the char-code at index 0 in X (the first and only one).
        s16    //   Convert this to a hexadecimal string.
               // Implicit: output result of last expression

Talvez seja melhor mostrar outra etapa: os atalhos unicode. Nesse caso, poderíamos salvar 2B com eles. Além disso, você pode adicionar que pode deixar de fora certas coisas no final. Isso economizaria outro byte.
Lucas

Uma excelente cartilha, obrigado, ETH. Acho que há o suficiente para começar alguns desafios simples.
Shaggy

Combinando isso com o que eu colhi do README até agora, eu estaria correto se o exemplo acima pudesse ser abreviado ainda mais Um_c s16?
Shaggy

Ou, mais curto ainda ¡Xc s16:?
Shaggy

11
@ Shagy Você está correto! Cara, você já descobriu isso rápido ;-) Vou adicionar algumas dicas básicas de golfe no Japt (como atalhos Unicode e outros), provavelmente como outras respostas.
ETHproductions

8

Compactando matrizes de seqüência de caracteres

ATUALIZAÇÃO: As ferramentas apresentadas nesta dica foram reescritas, aprimoradas e integradas ao meu intérprete Japt . Para obter os melhores resultados, é recomendável usar esse compressor sobre qualquer um dos links abaixo. Vou revisitar esta dica quando tiver mais tempo e reescrevê-la com o novo compressor em mente.

Introdução

Se você tiver uma matriz de seqüências de caracteres em seu código, a maneira mais óbvia de compactá-la seria executar cada sequênciaOc individualmente. Para os fins desta dica, trabalharemos com a matriz ["lollipop","marshmallow","nougat","oreo"], que pesa 42 bytes inicialmente. A execução de cada string Ocnos fornece:

[`lo¥ipop`,`Ú\hÚaow`,`Í`,`eo`]

Agora são 33 bytes, uma economia decente.


Passo 1

Mas podemos fazer melhor. Se unirmos a matriz a uma cadeia separada de nova linha, podemos nos livrar dos colchetes, vírgulas e reticulares estranhos e dividir na nova linha para obter nossa matriz. A aplicação disso ao nosso exemplo de matriz nos dá o seguinte:

`lo¥ipop
Ú\hÚaow
Í
eo`·

Abaixo de 26 bytes agora.


Passo 2

Mas , podemos fazer melhor ainda! Poderíamos usar uma letra minúscula para delimitar as strings em vez de uma nova linha, que pode ser incluída na compactação. znão é usado em nenhuma das nossas strings, então vamos explicar isso e ver como vamos.

`lo¥ipopzÚ\hÚaowzÍzeo`qz

Ah, nozes - nenhuma melhoria lá; nossa contagem de bytes aumentou em um! Pode haver outra carta que você poderia usar, mas, dependendo de suas cordas, poderia haver muito poucos para tentar - em nosso exemplo, existem 11: b,c,d,f,j,k,q,v,x,y,z. Tentar cada um deles seria bastante tedioso, e é aí que esta ferramenta útil entra; alimente-o com suas seqüências separadas de nova linha e ele tentará delimitar as seqüências com cada letra que não estiver contida em nenhuma delas e na saída:

  • a menor corda compactada,
  • o delimitador usado e
  • seu comprimento.

A execução de nossas seqüências de amostra mostra que bdá os melhores resultados:

`lo¥ipáæqrÚaowbÍÞo`qb

E aí está, temos apenas 24 bytes.


etapa 3

Mas podemos fazer ainda melhor! Se a ordem das seqüências de caracteres em sua matriz não importa, talvez exista uma permutação diferente combinada com um delimitador diferente que possa funcionar ainda mais. Tentar cada possibilidade será muito mais entediante. Com nossas 4 cordas, existem 24 permutações diferentes para tentar. Com cada uma das 11 letras possíveis que se tornam 264! É aí que esta ferramenta entra em jogo. Novamente, alimente suas seqüências de caracteres separadas por nova linha e ele tentará todas as combinações de todas as permutações e todas as letras delimitadoras, produzindo:

  • a ordem das strings na menor string compactada,
  • a corda compactada,
  • o delimitador usado e
  • seu comprimento.

Correndo nossas cordas de amostra através dele mostra que "nougat","oreo","lollipop","marshmallow"com bcomo delimitador dá os melhores resultados, com uma contagem de bytes finais de apenas 23:

`ÍÞo½o¥ipáæqrÚaow`qb


Dica de bônus: Compactação de matriz inteira

Você pode aplicar o mesmo princípio a matrizes de números inteiros, primeiro convertendo cada uma em uma base mais alta. Usando este exemplo, matriz de 36 bytes:

[588181,156859,595676,475330,680474]

Podemos reduzir isso para 29 bytes, primeiro convertendo-o em uma matriz de 32 strings base e depois executando-o no primeiro programa de compactação:

`huclt4p5r5ÛÊg62tkogq`qt mnH

Ou tão baixo quanto 27 bytes usando o segundo programa:

`4p5Ïcl5ÛÊg62tkogq`qt mnH

Você pode salvar outro byte ou 2 além disso, movendo a conversão de número inteiro para um método que você já está executando na matriz.


Notas

  1. Não se esqueça de levar em consideração os q<letter>(<space>)custos de 1 ou 2 bytes extras ·. Embora, você pode ser capaz de usar um dos atalhos Unicode para obter uma volta byte, dependendo do seu delimitador ( é o mesmo que ql<space>, por exemplo).
  2. Uma palavra de cautela ao usar a última ferramenta: quanto mais strings você tiver, mais permutações existirão e mais lento o programa será executado, até que ele acabe. Conforme detalhado acima, com nossas 4 seqüências de amostra e 11 letras possíveis para tentar, existem 264 combinações possíveis, aumente o número de cadeias em apenas 1 com as mesmas 11 letras e já temos 1320 combinações para tentar. (Você pode usar esta ferramenta para contar o número de combinações, se desejar).

Créditos

  • Oliver, pela inspiração para criar as ferramentas encontradas nesta dica.
  • ETHproduções para revisão.

6

Comprimindo cordas

Japt (atualmente) usa a biblioteca shoco para compactação de strings. Você pode compactar uma sequência arbitrária usando Oc, desde que contenha execuções de letras minúsculas:

Oc"Hello, World!"

Isso gera HÁM, WŽld! (bem, Žtecnicamente é um caractere não imprimível). Você pode descompactar isso envolvendo-o em backticks:

`HÁM, WŽld!`

Teste online!

Como alternativa, você pode usar a Odfunção para descompactar uma sequência arbitrária. Isso geralmente não é útil, mas tem seus objetivos ...


Então, se eu estivesse respondendo o "Olá, mundo!" desafio, eu usaria apenas HÁM, WŽld!ou precisaria ser colocado em retalhos? Eu estou adivinhando o último.
Shaggy

2
@ Shaggy Ao responder uma pergunta, você precisa incluir todo o código, para que seja `HÁM, WŽld! neste caso
Martijn Vissers

6

Encurtando números com códigos de char

No Japt, você pode usar #, seguido de um caractere para criar um código de char. Isso é útil ao diminuir números maiores.

Como o @ETHproductions mencionado, isso funciona apenas em execuções de três dígitos no intervalo de 100 a 255, a menos que você esteja disposto a mudar para UTF-8.

Exemplos:

123 pode ser reduzido para #{

101 pode ser reduzido para #e

Você pode até encadear isso juntos:

123101 pode ser reduzido para #{#e

Você pode usar String.fromCharCode(123)em JavaScript ou 123dem Japt para encontrar o caractere apropriado.

String.fromCharCode(123) retorna {


Obrigado, @obarakon, ótima dica para fazer a bola rolar; String.fromCharCode()é um daqueles (muitos!) métodos JS terrivelmente longos que podem armazenar sua contagem de bytes. Presumivelmente, estes seriam considerados inteiros? ou seja, se eu precisar do número inteiro 123em uma solução, eu poderia usar #{para salvar um byte.
Shaggy

11
Sim, esses são números inteiros. Se você adicionar a -Qbandeira em sua janela de entrada, você pode visualizar melhor o tipo de saída: aspas em torno de cordas , arranjos , etc.
Oliver

11
Você deve mencionar que String.fromCharCode(123)funciona em JavaScript, mas você pode fazer 123dem Japt para obter o mesmo resultado ;-) Além disso, isso só funciona em execuções de três dígitos no intervalo 100- 255(a menos que você queira mudar para UTF-8)
ETHproductions

@ETHproductions Boa chamada, atualizada!
Oliver

5

Dica rápida: matriz vazia []

Japt tem uma constante para uma matriz vazia: A. Mas, para acessá-lo, você deve colocar um ponto ;e vírgula no seu programa para usar as constantes alternativas do Japt, caso contrário A, será 10. Então, usando ;Arealmente oferece um 0 byte economizando mais [], mas vai poupar bytes Caso você precisa atribuir a matriz a uma variável (por exemplo, A=[]).

No entanto, se (e somente se) seu programa não estiver recebendo nenhuma entrada, você poderá acessar a matriz vazia com apenas 1 byte usando a Nvariável, que é a matriz de entradas - sem entradas, ela estaria vazia. Experimente aqui .

Isso também tem o benefício adicional de permitir que você use os valores constantes padrão no seu programa e, em alguns casos, ainda economize bytes, ;Amesmo quando o programa estiver recebendo informações, graças aos atalhos para s1e s2.


2
Uau, eu não tinha pensado em usar N, boa ideia.
ETHproductions

2
Bom, @Shaggy!
197 Oliver

4

Avaliando JavaScript

O Japt permite executar o JavaScript bruto, envolvendo-o $...$.

Por exemplo, $alert("hello world")$

Isso pode ser encurtado, tirando partido de auto-fechamento de Japt $e ).

$alert("hello world")$ pode ser reduzido para $alert("hello world"

Compactando JavaScript

Você também pode compactar o JavaScript usando Ox.

Se houver uma função JavaScript que você deseja usar, digamos screen.width, você pode compactar a string "screen.width"usandoOc e inserindo o resultado entre Ox` ... `

Observe que você não precisa fechar aspas no Japt quando não for seguido por mais nada.


@ Shaggy Você precisa Oxavaliar a string. Caso contrário, você apenas enviaria o texto "screen.width". Exemplo
Oliver

4

Conheça as bandeiras

De acordo com o meta consenso mais recente (dez 2017) , os sinalizadores de linha de comando não são mais contados em bytes. É realmente uma ótima notícia para o Japt, pois possui muitos sinalizadores para tratamento extra na entrada / saída.

Todos os sinalizadores disponíveis no Japt são descritos abaixo, na ordem da avaliação . As bandeiras no mesmo grupo são exclusivas uma da outra. Note-se que as bandeiras em diferentes grupos podem ser usados em combinação, resultando em algo como este :)

mdefæ

Todo o programa é mapeado sobre o primeiro argumento ( U).

Se houver mais argumentos, eles serão passados ​​como estão (ou seja, não mapeados em pares). Caso contrário, o segundo argumento é o índice e o terceiro é a matriz inteira, assim como U.m. Se Ué um número, é convertido em intervalo; se string, é convertido em matriz de caracteres e os resultados são unidos.

  • -m: Aplica o acima e nada mais.
  • -d: Retorna truese algum resultado for verdadeiro, falsecaso contrário.
  • -e: Retorna truese todos os resultados forem verdadeiros, falsecaso contrário.
  • -f: Retorna a matriz de elementos Ucujos resultados são verdadeiros.
  • : Aplica -fe retorna seu primeiro elemento.

gh

Pega um elemento no índice especificado.

  • -g: Pega o primeiro elemento (índice 0).
  • -gX: Pega o elemento no índice X(pode ser qualquer número inteiro positivo).
  • -h: Pega o último elemento.

Converta o resultado em booleano.

  • -!: Aplicar booleano não.
  • : Aplique booleano não duas vezes (retorna a veracidade).

N

Converta o resultado em número. O plus unário é usado.

PRSQ

Converta em string de algum tipo.

  • -P: Junte-se à matriz com "".
  • -R: Junte-se à matriz com "\n".
  • -S: Junte-se à matriz com " ".
  • -Q: Aplicar JSON.stringify(pode ser qualquer objeto, não apenas uma matriz). Exemplo .

x

Aplica a função xà saída. (É literalmente x, não "nenhuma função do alfabeto em minúsculas".)

  • Matriz: Soma.
  • String: apara de ambas as extremidades.
  • Número: Arredonde para inteiro.

2
Observe que o uso de sinalizadores não conta como envio do Japt, mas sim como envio do idioma Japt-com-aqueles-específicos-sinalizadores.
Nit

3

Atalhos Unicode

Há muitas estruturas comuns em Japt que simplesmente não podem ser armazenados em um único caractere ASCII, como qS , p2 , mX{, , etc. Então, para contornar esta situação, Japt tem "atalhos Unicode", que são caracteres no intervalo \xA1- \xDE( ¡- Þ) que se expandem para essas estruturas comuns. Você pode encontrar uma lista completa delas nos documentos do intérprete .

Além disso, @significa XYZ{e _representa Z{Z, para funções ajudar a construir. Então, vamos jogar nosso programa de exemplo de outra resposta :

UmX{Xc0 s16}

Em primeiro lugar, podemos substituir X{Xpor _, o que nos dá:

Um_c0 s16}

Em seguida, podemos substituir m_por ®salvar outro byte:

U®c0 s16}

Ou podemos substituir X{por @, o que nos dá:

Um@Xc0 s16}

Isso nos permite usar o ¡atalho para salvar dois bytes:

¡Xc0 s16}

Um desses dois caminhos pode ser reduzido em 1 byte mais que o outro. Você pode descobrir qual?


11
®c s16por 6 bytes - eu ganho um cookie ?!
Shaggy

@Shaggy Você pode economizar mais 1 byte, se você olhar duro o suficiente ...;)
ETHproductions

Seria ®c sG?
Shaggy

11
Sim! Eu acho que é o mais baixo que você pode ir. Bem feito! :-)
ETHproductions

2
Incrível olhando para trás, vendo a progressão de Japt em poucos meses. Agora isso pode ser alcançado com csG.
Shaggy

3

Aproveite as variáveis ​​predefinidas

Variáveis A- Ssão predefinidas para valores comuns que levam mais de um byte para representar no Japt:

  • A- Gsão 10- 16.
  • Hé 32, Ié 64, Jé -1, Lé 100.
  • Ké definido como new Date(), que você pode manipular de várias maneiras.
  • Me Osão objetos com várias funções úteis. Você pode aprender mais nos documentos.
  • Pé a sequência vazia, Qé uma marca de citação, Ré uma nova linha e Sé um espaço.
  • Testá definido como 0, para que você possa usá-lo como um acumulador, se necessário.

Se o primeiro caractere do programa for um ponto e vírgula ; e- , A-Lredefina da seguinte maneira:

  • Aé a matriz vazia [].
  • B é "ABCDEFGHIJKLMNOPQRSTUVWXYZ" .
  • C é "abcdefghijklmnopqrstuvwxyz" .
  • D é "QWERTYUIOP\nASDFGHJKL\nZXCVBNM" .
  • Eé "[a-z]"eF é "[A-Za-z]"(útil antes de adicioná-los como recursos de regex)
  • Gé 36, Hé 65eI é 91(útil para intervalos de alfabeto).
  • J é uma única vírgula; L, um único período.

Hoje única A, B, C, e Dnesta lista são realmente úteis. Estou planejando adicionar um sistema melhor que permita até 256 variáveis ​​de dois bytes, que serão predefinidas para esses valores e muito mais.


3

Use funções automáticas

Você provavelmente já sabe disso @e _é um atalho para XYZ{e Z{Z, respectivamente (abordado nos atalhos Unicode resposta dos ). Mas, às vezes, você pode tornar as funções ainda mais curtas.

Suponha que você tivesse uma matriz de caracteres e desejasse mapear cada caractere para seu código de char. Você pode fazer isso com um destes:

mX{Xc} 
m_c} 

Mas há uma maneira melhor. Se um método ou operador for o primeiro item após outro método ou a (, ele será transformado em uma sequência. Portanto, essas duas linhas são equivalentes:

r'a'b  // Replace all "a"s with "b"s; transpiles to .r("a","b")
ra'b   // Does the same thing, 1 byte less; transpiles to the same thing

Mas como isso ajuda em nossas funções? Bem, a maioria dos métodos que aceitam funções, se for fornecida uma string representando um método ou operador, a interpretará como uma função. O que significa que você também pode fazer isso:

m_c}  // Map each item to its char code
m'c   // Does the same thing, 1 byte less
mc    // Also does the same thing, 2 bytes less

Eu chamo essas "funções automáticas". Existem várias variedades diferentes:

  • m@Xc}mc
  • m@Xc1}mc1
  • m@X+1}m+1
  • m@1+X}m!+1
  • m@2pX}m!p2

Espero que você entenda a idéia. Para trocar os argumentos, basta prefixar o método ou operador com !.


Vale a pena notar aqui que o uso de funções automáticas também pode permitir economias adicionais com o uso de atalhos? por exemplo, m@2pXÃm!p2<space>m!².
Shaggy

Woah! Não pensei em usar uma string no mapa, nem sabia que era possível. Talvez eu salve alguns bytes graças a isso no futuro.
RedClover 12/01

Ei, @Soaku, de alguma forma eu senti falta de você ter respondido com Japt, então permita que eu lhe dê as boas-vindas tardias! Espero que você tenha gostado de usá-lo até agora. Se você tiver alguma dúvida, sugestão ou apenas quiser conversar, sinta-se à vontade para se juntar a nós na sala de bate-papo do Japt (Github geralmente funciona bem para os dois primeiros;))
ETHproductions

3

Atribuição variável implícita

Sempre que você inicia uma nova linha em Japt, o resultado da linha anterior é automaticamente atribuído a uma das variáveis ​​de entrada ( U- Z), com a primeira linha sendo Ua segunda Ve assim por diante.

Vamos dar um exemplo: digamos que você queira criar duas matrizes para trabalhar, uma contendo os números de 1 a 10 e a outra contendo seus quadrados. O longo caminho para fazer isso seria assim:

U=Aõ V=Um² [do something with the arrays]

Porém, usando a atribuição automática de variáveis, isso pode ser reduzido para:

Aõ
Um²
[do something with the arrays]

Nós salvamos 4 bytes lá. Mas, nesse caso, podemos salvar mais um byte porque a matriz de 1 a 10 é atribuída Ue Upode ser omitida em certos cenários :

Aõ
m²
[do something with the arrays]

Cuidado

Uma coisa a ter cuidado com esta dica é que você não substituirá nenhuma variável de entrada que possa ser necessária posteriormente no seu programa. Isso pode ser evitado deixando uma ou mais linhas vazias no início. No exemplo a seguir, as 2 matrizes serão atribuídas às variáveis V& W, em vez de U& V:


Aõ
Vm²
[do something with the arrays]

3

Conheça o Javascript

Como qualquer código Japt é executado como JS transpilado, o bom entendimento dos operadores JS e dos métodos internos ajuda muito na troca de partes do código Japt.

Dicas JS relevantes

[]Vm@...
...
  • Curto-circuito
  • Divisão com números
    • Isso pode ser generalizado para qualquer método que aceite seqüências de caracteres, mas não números. Um número passado para lá será convertido implicitamente em uma string, geralmente salvando um byte (por exemplo, 0over '0).

Funções internas relevantes do JS

Observe atentamente quais parâmetros são passados ​​para argumentos de função.

Para métodos de string, é bom saber como os comportamentos diferem entre passar uma string ou regex com ou sem gsinalizador.


3

Use várias linhas quando necessário

Para a maioria dos desafios não muito difíceis, você pode expressar a solução em apenas uma linha do Japt, como uma sequência de aplicação de funções internas. Porém, as mais complexas exigirão o uso de construções em loop, recursão ou reutilização de grandes pedaços de código. É aqui que entra a programação em várias linhas.

Remover parênteses de fechamento

Tarefa : Dada uma matriz de números, emparelhe cada elemento com o índice ao quadrado e classifique-o pela soma.

[5,1,17,9,3] => [[5,0],[1,1],[17,4],[9,9],[3,16]] => [[1,1],[5,0],[9,9],[3,16],[17,4]]

A solução de uma linha é íUm@Yp2})ñx, mas })custa dois bytes (e não há atalho de um byte). Você pode remover })simplesmente movendo o final ñxpara a próxima linha, para que o código fique assim:

íUm@Yp2
ñx

e o JS transpilado se torna:

U = U.í(U.m(function(X, Y, Z) { return Y.p(2) })); U.ñ("x")

Você pode ver claramente que isso faz o mesmo que a solução de uma linha, apenas atribuindo o resultado intermediário novamente U.

Recursar com argumentos implícitos

A função de recursão ßassume todos os UVWXYZparâmetros implícitos, se não especificado. Ué obviamente a entrada principal, mas você pode usar qualquer um VWXYZdeles para acompanhar outros valores necessários. Por exemplo, você pode fazer algo como o seguinte:

(modify input and implicit assign to U)
(modify V and implicit assign to V)
(test something and call ß without arguments; U and V are passed automatically)

Como alternativa, se tudo o que você deseja é uma variável temporária, você pode usar a atribuição em linha, como (T=...), como a variávelT (0) raramente é usada como está.

Reutilizar uma função longa

Para isso, acho que não consigo criar um bom exemplo de tarefa, por isso vou fazer referência à única solução que essa dica foi usada e apenas esboçar algumas idéias gerais.

  • Para reutilizar uma função, você precisa armazená-la em uma variável. Começando uma linha com a função de abertura {, @ou _faz o trabalho. Como alternativa, você também pode fazer algo como(T=@...}) incorporar a atribuição de função a uma linha mais complexa.
  • Na verdade, não é trivial chamar a função armazenada. Suponha que Vé uma função e queremos chamar V(U)em JS. VUnão funciona, pois significa simplesmente V,U. V(Utambém não; EstáV,(U) . Mesmo os métodos de função não são muito úteis. A melhor maneira que encontramos é:
    • [U]xV (mapa e soma) se o resultado for número
    • UmVif Ué um único caractere e Vretorna uma string ou
    • $V($Uou [U]mV gem geral.
  • No entanto, é fácil mapear ou fazer um loop com ele. Para mapear sobre uma matriz, use UmV. Para encontrar o primeiro número inteiro que satisfaça V, use Va.

2

Diversão com funções automáticas

Como acompanhamento da dica geral da ETH sobre funções automáticas , esta dica fornecerá alguns exemplos específicos de truques de economia de bytes que você pode obter com eles, os quais adicionarei ao pensar em mais.


Obtenha o maior número inteiro em uma matriz.

Suponha que temos a matriz [3,1,4,2]atribuída à variável Ue desejamos recuperar o maior número dela. Nós poderia fazê-lo em 4 bytes, classificando a matriz e, em seguida, avançar o último elemento:

Un o

A desvantagem disso é que modificamos a matriz original; Ué agora o [1,2,3]que nem sempre é desejável. Felizmente, há uma maneira de fazer isso sem modificar a matriz que também é um byte menor:

Urw

O que fizemos lá reduziu a matriz usando o wmétodo, que, quando usado em um número inteiro, retorna o maior do número inteiro e o argumento do método (por exemplo, 2w5retorna 5). Portanto, o acima é equivalente a UrÈwYou UrXY{XwY}. Observe, porém, que essa dica não funcionará no caso de todos os números inteiros na matriz serem negativos.


11
Nota lateral: Estou planejando adicionar funções para obter o mínimo e o máximo de uma matriz, embora provavelmente apenas na v2.
ETHproductions

2

Quando não usarí

íé um built-in útil que emparelha zipduas matrizes ou seqüências de caracteres e, opcionalmente, mapeia cada par por meio de uma função. No entanto, atualmente há alguns problemas menores quando são fornecidas matrizes ou strings desiguais:

  • Se a primeira matriz tiver mais itens que a segunda, os itens inexistentes na segunda serão dados como undefined.
  • Se a segunda matriz tiver mais itens que a primeira, interromperá o processamento no final da primeira matriz.

Isso pode dificultar, digamos, comparar duas cadeias irregulares e levar o caractere com o ponto de código mais alto de cada par. Mesmo se você souber que Userá o mais longo, ainda serão necessários muitos bytes para resolver esta tarefa simples:

UíUç hV @[XY]n o

Em vez disso, o que você poderia fazer seria receber a entrada como uma matriz de duas cadeias, transpor a matriz e y, em seguida, mapear cada linha para o resultado correto:

Uy m_q n o

Isso tem a vantagem de sempre preencher a corda mais curta com espaços, tornando-o um pedaço de bolo para percorrer a totalidade de ambas as cordas.

Exemplos da vida real: 1 , 2


2

Gere a faixa ASCII

Atualização: o Japt agora tem uma constante para o intervalo ASCII; o valor alternativo para E, acessível com ;. Veja esta dica para obter mais informações sobre as constantes de Japt.

Embora Japt (ainda) não tenha um built-in para o intervalo ASCII, você pode gerar uma matriz de caracteres em apenas 5 bytes:

95odH

Tente


Como funciona

95ocria o intervalo [0,95)com cada elemento sendo passado pela função automática d que, quando usada em um número, retorna o caractere nesse ponto de código. Passe um número como argumento para o dmétodo, neste casoH , a constante Japt para 32, e ela será adicionada ao número original antes de ser convertida.

Uma solução equivalente em JavaScript seria:

[...Array(95)].map((_,x)=>String.fromCharCode(x+32))

Personagens aleatórios

Para obter um caractere aleatório no intervalo ASCII, use em övez disso, que retorna um número aleatório do intervalo [0,X), onde Xé o número no qual ele é executado.

95ö dH

Ou, para obter uma matriz de vários caracteres aleatórios, transmita o número de caracteres de que você precisa como argumento ö. O seguinte retornará 10 caracteres:

95öA mdH

1

Remova caracteres estruturais desnecessários

Por caracteres estruturais, quer dizer {}, (), $, mesmo "e `. Normalmente, você pode remover esses caracteres sempre que eles ocorrem no final de um programa (por exemplo UmX{Xc +"; "} -> UmX{Xc +"; ).

Além disso, você pode remover parênteses ou espaços sempre que eles aparecerem nos seguintes locais:

  • Contra um ponto e vírgula ;(ou o final do programa);
  • À direita de {(e por extensão @) ou [, ou à esquerda de ]ou }.

Além disso, raramente são necessárias vírgulas para separar argumentos. Se você escreve AB, por exemplo, Japt sabe o que você quer dizer Ae Bseparadamente. Você realmente precisa de uma vírgula para separar dois literais numéricos, comoUs2,5 .

Por fim, se houver um Uno início de um programa ou após um {ou ;, seguido de uma chamada de método (letra minúscula ou atalho Unicode relacionado) ou qualquer operador binário excluindo +e -(* , &, ==, etc.), você pode remover a Usalvar um byte e Japt irá inseri-lo para você.


Eu encontrei algumas outras instâncias em que Upode ser omitido, mesmo quando não está no início do programa.
Shaggy

@ Shagy Oh certo, ele também funciona depois de um {ou ;. Existem outros que você conhece? (Já faz um tempo desde que eu codifiquei esse recurso: P)
ETHproductions

Não consigo pensar neles do alto da minha cabeça; Vou verificar novamente quando voltar ao meu computador amanhã.
Salsicha

1

Modificar o último elemento em uma matriz

Às vezes, pode ser necessário modificar o último elemento em uma matriz, então aqui está uma explicação de uma maneira curta de fazer isso. Trabalharemos com o array [2,4,8,32]atribuído à variável de entrada Ue dividimos o último número inteiro (32 ) por 2.

A maneira óbvia de conseguir isso seria com esta solução de 9 bytes ( Demo ):

UhJUgJ /2
  • hnx define o elemento no índice n comox .
  • gn retorna o elemento no índice n .
  • J é a constante Japt para -1 qual, graças ao suporte de Japt ao índice negativo, nos permite trabalhar com o último elemento em uma matriz; útil quando você não sabe o tamanho da matriz.
  • E /2 é simplesmente a divisão por 2.

Assim, os conjuntos acima do elemento no índice -1na matriz para o elemento no índice -1na matriz dividido por 2. Ou em JavaScript: U[3]=U[3]/2. Quando você escreve assim, parece uma maneira muito demorada de fazê-lo. Felizmente, não é um caminho mais curto; poderíamos exibir o último elemento da matriz, modificá-lo e enviá-lo de volta para a matriz. A execução de cada uma dessas operações individualmente levaria mais de 9 bytes, mas podemos executá-las todas de uma vez por apenas 7 bytes, economizando 2 bytes ( Demo )

UpUo /2

Traduzido para JS, é o equivalente a:

U.push(U.pop()/2)&&U
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.