Dicas para jogar golfe em JavaScript


133

Que dicas gerais você tem para jogar golfe em JavaScript? Estou procurando idéias que possam ser aplicadas para codificar problemas de golfe em geral que sejam pelo menos um pouco específicos para JavaScript (por exemplo, "remover comentários" não é uma resposta).

Nota: Consulte também Dicas para jogar golfe no ECMAScript 6 e acima


Eu estava realmente pensando, é permitido colocar variáveis ​​em global (salva var)? E o código de golfe JavaScript deve ser uma função ou gerar algo diretamente? Sinceramente, acho que isso pode fazer muita diferença.
Pimvdb 27/05

1
@primvdb: É permitido, mas você deve ter cuidado, pois pode causar efeitos colaterais se uma função for chamada várias vezes e estiver manipulando variáveis ​​globais, ou se for uma função recursiva.
Mellamokb

Respostas:


108

Fantasia para loops

você pode usar o padrão para loop de maneiras não padronizadas

for ( a; b; c )

é essencialmente equivalente a:

a;
while ( b )
{
  ...
  c;
}

portanto, um bom truque é escrever seu código com um whileloop e depois dividi-lo nas a,b,cpartes em um forloop.

Alguns exemplos que escrevi :

for(x=y=n;!z;x--,y++)z=i(x)?x:i(y)?y:0
for(a=b=1;b<n;c=a+b,a=b,b=c);

Encadear seus setters

Se você estiver inicializando ou redefinindo vários valores, encadeie o valor a todas as variáveis ​​que precisam:

a=b=1;

Fundição implícita

Não verifique seus tipos, use-os como estão. parseInt()custa 10caracteres. Se você precisar eliminar uma string, seja criativo:

a='30';
b='10';
c = a + b; //failure
c = parseInt(a) + parseInt(b) //too long

c = -(-a-b); //try these
c = ~~a+~~b;
c = +a+ +b;
c = a- -b;

Evitar ponto e vírgula

JavaScript tem inserção automática de ponto e vírgula. Use-o com frequência e bem.

One-liners

Economize entre colchetes, empurrando o máximo possível em linhas únicas ou parâmetros:

a( realParam1, realParam2, fizz='buzz' )

Operadores de incremento / decréscimo

a = a - 1;
foo(a);

e

foo(a);
a = a - 1;

pode ser facilmente reescrito como

foo(--a);

e

foo(a--);

respectivamente.

Use thisou em selfvez de windowno contexto global

economia de 2 caracteres auto-explicativa.

Use notação de colchete para acesso repetido à propriedade

Esse é definitivamente um ato de equilíbrio entre o comprimento do nome da propriedade e o número de acessos. Em vez de chamar a.longFunctionName()com notação de ponto duas vezes, é mais curto salvar o nome e chamar a função via notação entre colchetes:

a.longFunctionName(b)
a.longFunctionName(c)
//42

-vs-

a[f='longFunctionName'](b)
a[f](c)
//34

isso é especialmente eficaz com funções como as document.getElementByIdquais podem ser reduzidas a d[e].

Nota:

Com a notação entre colchetes, o custo é de 6 + name.lengthcaracteres na primeira vez. Cada acesso subsequente tem um custo de 3caracteres.

Para notação de pontos, todos os acessos custam name.length + 1(+1 para os .) caracteres.

Use este método se 6 + name.length + (3 * (accesses - 1)) < accesses * (name.length + 1).

len = comprimento do nome da propriedade
i = acessos mínimos para aproveitar

len | i 
========
1   |  
2   |  
3   | 7 
4   | 4 
5   | 3 
6   | 3 
7   | 3 
8+  | 2 

O número de acessos também pode abranger vários objetos. Se você acessar .length4 ou mais vezes em matrizes diferentes, poderá usar a mesma variável segurando a string 'length'.


5
c = ~~a-~~bdeveria ser c = ~~a+~~b. Além disso, você pode converter implicitamente em número inteiro usando |0, por exemplo Math.random()*6|0.
#

7
É mais barato coagir uma string a um número com o operador unary plus. Se ae bsão cadeias, você pode fazer +a+ba conversão para número e adicioná-las.
Peter Olson

8
Eu juro que eu vou usar d- -bno meu código algum dia ...
John Dvorak

4
+ a + b não funciona (pelo menos no meu ...) // a = "1", b = "1", + a + b // dá "11"
imma

2
Para "Usar acesso à matriz para chamadas de função repetidas", se você estiver usando a função mais de duas vezes no mesmo objeto , o que é um pouco mais curto é atribuir a função a um novo membro comoa.f=a.longfunctionname;a.f(b);a.f(c);a.f(d)
Martin Ender,


56

Use o operador de vírgula para evitar chaves (também se aplica a C ):

if(i<10)m+=5,n-=3;

Ao invés de

if(i<10){m+=5;n-=3}

que é um caractere mais longo.


2
O ponto-e-vírgula é necessário no final da primeira amostra?
Wjl 20/08/12

4
@wjlafrance: só não seria necessário se estiver no final de uma linha.
precisa saber é o seguinte

48

Menor geração de números aleatórios

Se você precisar de um booleano aleatório ( 0ou 1):

new Date&1 // equivalent to Math.random()<0.5

Se você precisar de um número inteiro aleatório 0 <= n < 1337:

new Date%1337 // equivalent to Math.floor(Math.random()*1337))

Isso funciona porque a Dateé armazenado internamente em JavaScript como a quantidade de milissegundos desde uma época, e new Dateestá sendo coagido 123somebignumber456quando você tenta fazer cálculos inteiros nele.

Certamente, esses números "aleatórios" realmente não serão tão aleatórios, especialmente se você os chamar várias vezes em rápida sucessão, então lembre-se disso.


1
Acabei de lembrar esta resposta ao ler Mais programadores de falsidades acreditam no tempo : “21. Se você criar dois objetos de data, um ao lado do outro, eles representarão a mesma hora. (um fantástico gerador Heisenbug) ” .
Sebastian Simon

39

Você pode usar a forma literal de objeto de get / set para evitar o uso da palavra-chave function.

var obj = {
  get f(){
    console.log("just accessing this variable runs this code");
    return "this is actually a function";
  },
  set f(v){
    console.log("you can do whatever you want in here, passed: " + v);
  }
};

1 && obj.f; // runs obj.[[get f]]
obj.f = Infinity; // runs obj.[[set f]](Infinity)

a parte getter / setter foi realmente útil. thx
gion_13 14/03/12

1
Na verdade, ainda melhor é um método de objeto, se você o usar apenas <= 2 vezes. Por outro lado, as funções de seta são muito melhores para reduzir caracteres, pois servem quase ao mesmo objetivo, e as classes raramente são úteis no código de golfe.
Isiah Meadows

se o suporte for importante, as funções de seta não são suportadas no fx. ie11
Jim Wolff

35

Este é menos conhecido e menos usado, mas pode ser impressionante se usado na situação certa. Considere uma função que não aceita argumentos e sempre retorna um número diferente quando chamado, e o número retornado será usado em um cálculo:

var a = [ 
    Math.random()*12|0,
    Math.random()*11|0,
    Math.random()*10|0,
    /* etc... */ 
];

Normalmente, você pode encurtar essa função usando um nome de variável com uma letra:

var r=Math.random,a=[r()*12|0,r()*11|0,r()*10|0,r()*9|0,r()*8|0,r()*7|0,r()*6|0,r()*5|0];

Uma maneira melhor de reduzir o comprimento é abusar valueOf, o que permite economizar 2 caracteres por chamada. Útil se você chamar a função mais de 5 vezes:

var r={valueOf:Math.random},a=[r*12|0,r*11|0,r*10|0,r*9|0r*8|0,r*7|0,r*6|0,r*5|0];

8
Ou, você pode fazê-lo como um destes: let a=[5,6,7,8,9,10,11,12].map(x=>x*Math.random()|0)ou let a=Array(7).map((_,i)=>i*Math.random()|0+5)36 ou 42 bytes salvos, respectivamente.
Isiah Meadows

É possível substituir r()ou reduzi-lo?
NiCk Newman 03/11/2015

3
r={valueOf:Math.random}Isso é apenas genial: D
ETHproductions

1
@Isiah, bem, sim, você pode fazer isso agora :-D
Andy E

32

Aproveitando os operadores de curto-circuito

Em vez de ifinstruções longas ou usar operadores ternários, você pode usar &&e ||reduzir seu código. Por exemplo:

var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);

return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : null;

pode se tornar

var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);

return match && decodeURIComponent(match[1].replace(/\+/g, ' '));

O ||operador é frequentemente usado dessa maneira para definir padrões:

evt = evt || window.event;

É o mesmo que escrever

if (!evt)
    evt = window.event;

Criando seqüências repetitivas usando Array

Se você deseja inicializar uma cadeia longa de um caractere específico, pode fazê-lo criando uma matriz com um comprimento de n + 1 , em que n é o número de vezes que deseja repetir o caractere:

// Create a string with 30 spaces
str = "                              ";

// or
str = Array(31).join(" ");

Quanto maior a corda, maior a economia.

Analisando números

Use +e ~operadores em vez de parseFloat()ou parseInt()ao unir um tipo de sequência que é apenas um número para um tipo de número:

var num = "12.6";
parseFloat(num) === +num;  // + is 10 characters shorter than parseFloat()

var num2 = "12"
parseInt(num2) === +num2;   // + is 8 characters shorter than parseInt()

var num3 = "12.6"
parseInt(num3) === ~~num3;  // ~~ is 7 characters shorter than parseInt()

var num4 = "12.6"
parseInt(num4) === num4|0;  // |0 is 7 characters shorter than parseInt()

Seja cauteloso, porém, outros tipos podem ser combinados com esses operadores (por exemplo, truese tornariam 1) uma string vazia ou uma string contendo apenas espaço em branco 0. Isso pode ser útil em determinadas circunstâncias, no entanto.


6
+1 para Criar seqüências repetitivas usando Array - não havia pensado nisso.
precisa saber é o seguinte

4
Para criar seqüências repetitivas, em ES6 você pode usarstr.repeat(count)
Oriol

26

Esgueirar a inicialização da variável na chamada prompt () para obter a entrada do usuário

n=prompt(i=5);     // sets i=5 at the same time as getting user input

ao invés de usar

n=prompt();i=5;

Como efeito colateral, ele exibe o valor de entrada na janela de prompt enquanto salva 1 caractere.


12
Isso também pode ser aplicado a qualquer função que não aceite argumentos.
Casey Chu

3
Mesmo quando a função aceita argumentos, ela pode ser útil, como [1,2,3].join('',i=5)nos casos em que salva um par de chaves.
DocMax

3
@ DocMax: Você pode usar um operador de vírgula para isso - i=5,[1,2,3].join().
Konrad Borowski

@ GlitchMr: Eu poderia, mas ele não salva nenhum personagem. Concordo que na maioria das vezes isso será mais limpo. Acho que ainda pode haver casos em que meu pedido pode salvar um caractere, embora eu não possa encontrar um no momento (e posso estar errado).
DocMax 4/13/13

@DocMax Somente se você estiver aproveitando o ASI.
Isiah Meadows

24

Combinar aninhado para loops:

// before:
for(i=5;i--;)for(j=5;j--;)dosomething(i,j)

// after:
for(i=25;i--;)dosomething(0|i/5,i%5)

Exemplo com valores diferentes para i/ j:

// before:
for(i=4;i--;)for(j=7;j--;)dosomething(i,j)

// after:
for(i=28;i--;)dosomething(0|i/7,i%7)

(Eu editei um) erro de digitação menor, mas muito inteligente! Observe que isso funcionará apenas em loops aninhados do mesmo tamanho (a menos que eu esteja errado).
Camilo Martin

1
@CamiloMartin Não, os loops não precisam ter o mesmo comprimento. O número resultante de iterações é i*je os operadores de divisão / módulo recuperam os valores individuais de ie j.
quietmint

@ user113215 Você está certo, incrível! :) Editei a resposta para incluir um exemplo.
Camilo Martin

23

Atalhos Unicode

Se você usa uma propriedade embutida em um grande desafio de golfe, pode alias cada propriedade a um equivalente de um caractere:

[Math,Number,S=String,Array].map(b=>
    Object.getOwnPropertyNames(b).map((p,i)=>
        b.prototype[S.fromCharCode(i+248)]=b[p]
    )
)

Depois de executar o código acima, você pode usá-lo assim:
"foo".Č(/.*/,'bar') // replaces foo with bar

Isso custa 118 bytes, portanto pode não ser útil em determinadas situações

Pode ser dependente do navegador e não tenho certeza se é mais curto with(Array){join(foo),...}ou que define variáveis ​​como propriedades usadas, with(Array){j=join,m=map...}mas ainda vale a pena mencionar.

    Math        Number              String              Array

ø   toSource    prototype           prototype           prototype
ù   abs         NaN                 quote               join
ú   acos        POSITIVE_INFINITY   substring           reverse
û   asin        NEGATIVE_INFINITY   toLowerCase         sort
ü   atan        MAX_VALUE           toUpperCase         push
ý   atan2       MIN_VALUE           charAt              pop
þ   ceil        MAX_SAFE_INTEGER    charCodeAt          shift
ÿ   clz32       MIN_SAFE_INTEGER    contains            unshift
Ā   cos         EPSILON             indexOf             splice
ā   exp         isFinite            lastIndexOf         concat
Ă   floor       isInteger           startsWith          slice
ă   imul        isNaN               endsWith            filter
Ą   fround      toInteger           trim                isArray
ą   log         parseFloat          trimLeft            lastIndexOf
Ć   max         parseInt            trimRight           indexOf
ć   min         length              toLocaleLowerCase   forEach
Ĉ   pow         name                toLocaleUpperCase   map
ĉ   random      arguments           normalize           every
Ċ   round       caller              match               some
ċ   sin                             search              reduce
Č   sqrt                            replace             reduceRight
č   tan                             split   
Ď   log10                           substr  
ď   log2                            concat  
Đ   log1p                           slice   
đ   expm1                           fromCharCode    
Ē   cosh                            fromCodePoint   
ē   sinh                            localeCompare   
Ĕ   tanh                            length  
ĕ   acosh                           name    
Ė   asinh                           arguments   
ė   atanh                           caller  
Ę   hypot           
ę   trunc           
Ě   sign            
ě   cbrt            
Ĝ   E           
ĝ   LOG2E           
Ğ   LOG10E          
ğ   LN2         
Ġ   LN10            
ġ   PI          
Ģ   SQRT2           
ģ   SQRT1_2         

Estou usando o google chrome, e todos estes estão dando indefinido.
SuperJedi224

Deve ser muito específico para o Firefox então. Desculpe pela inconveniência.
Bebe #

Por que esses são todos caracteres especiais? Por que não usar apenas ASCII imprimível? (mais fácil de digitar, mais fiável, e somente um byte para golfe)
Cyoce

Isso realmente não funciona Mathporque não possui um .prototypeatributo. Removendo Math, no entanto, consegui jogar isso em um snippet de 114 bytes que os atribui a letras de byte único. Você pode encontrá-lo aqui .
ETHproductions

1
Você também pode jogar minha solução em 106 bytes à custa de mover todas essas propriedades para o intervalo À- ÿ, que ainda possui 1 byte na codificação ISO-8859-1 (suportada pelo JS). Infelizmente no Firefox 50, infelizmente, o .localeComparemétodo é ativado ×, mas isso normalmente não deve ser um problema. fonte
ETHproductions

22

Converter um whileloop em um forloop geralmente é equivalente:

while(i--);
for(;i--;);

Mas a segunda forma pode ter a inicialização variável combinada:

i=10;while(i--);
for(i=10;i--;);

Observe que o segundo formulário é um caractere menor que o primeiro.


6
Ou, melhor ainda, use apenas para loops. Não há realmente nenhum caso em que o uso de um loop for resulte em código maior, tanto quanto eu experimentei.
Isiah Meadows

22

Abuso de exceção

no caso de literais de cadeia / caracteres serem proibidos, você pode usar um bloco try catch:

try{something0}catch(e){str=e.message.split(0)[0]}

agora stré igual"something"

se forem necessárias mais strings, você pode encadear com um número (por exemplo, zeros)

try{something0foo0bar0}catch(e){arr=e.message.split(0)}

agora arré igual["something", "foo", "bar", " is not defined"]


18

Se você estiver inicializando uma variável 1em todas as iterações de um loop (por exemplo, redefinindo uma variável em um loop externo para um loop interno), como o seguinte (da minha resposta a esta pergunta ):

for(j=n-2;p=1,j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;
          ^^^^

Como o resultado de uma condição como j++<=né 1sempre que é verdadeiro, é possível atribuir a condição diretamente à variável (porque quando ela se torna falsa, o loop para de ser executado e não importa mais):

for(j=n-2;p=j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;
          ^^^^^^^^

Você geralmente pode salvar 2 caracteres usando esse método. Atenciosamente, @ugorenpara a idéia nos comentários a essa resposta.


Para outro exemplo, também apliquei esse truque na minha resposta aqui com a expressão w=r=++c<S.lengthno loop for externo, salvando um total de 4 caracteres.


18

Se você puder aceitar scripts específicos do Spidermonkey (por enquanto), poderá usar as funções de seta do ECMAScript 6 . Em vez de escrever código como o seguinte.

a.map(function(x){return x*2}) // function? return?

Você pode encurtar assim.

a.map(x=>x*2)

17

Se você precisar verificar o NaN, não use isNaN(x), mas use x!=x, que é mais curto e também funciona.

if(isNaN(x)){
if(x!=x){

Observe que isso só funciona se typeof(x) === "number"; se for uma string, por exemplo, isNaN("string")retorna true, mas "string" != "string"retorna false. Agradecemos a Cyoce por apontar isso!


2
Esse é um uso genial dessa peculiaridade. +1
ETHproductions

Atenção: estes nem sempre são equivalentes: isNaN("string")retornos true, enquanto "string"!="string"retornos false(obviamente)
Cyoce

@Cyoce Bom ponto, obrigado! Eu editei minha resposta.
ProgramFOX

Em muitos casos, você pode até tentar if(!x){, se estiver detectando NaNexplicitamente.
Hohmannfan

1
A conversão xpara número, o +x!=+xtorna equivalente a isNaN(x), ainda assim, 2 caracteres mais curtos. Então, +"string"!=+"string"retorna verdadeiro.
Tomas Langkaas

15

Soma / produto / quociente da matriz

ES5 : 17 bytes

eval(a.join('+'))

ES6 : 15 bytes

eval(a.join`+`)

É claro que você pode trocar +por qualquer coisa que desejar, por exemplo, *por produto ou /por quociente.


14

Use uma operação bit a bit para arredondar um número para zero:

// do this
T=Math.random()*6+1|0

// or do this
T=~~(Math.random()*6+1)

(Fonte: tombamento de dados aleatórios )

A precedência do operador determina quais serão mais curtos no seu programa.


2
Isso também pode ser usado para coalescer uma entrada de string em um número inteiro, ou seja n=prompt()|0,.
Mellamokb

1
bit a bit é também super rápido em comparação com Math.floor: jsperf.com/floor-vs-bitwise
vsync

@vsync: Estranho. Eu entendo que math.floor seja duas vezes mais rápido que o bit a bit no Chrome 11.0.696.77.
precisa saber é o seguinte

muito estranho. para mim, ambas são mais ou menos as mesmas velocidades e super rápidas no Chrome, mas no FF o bit a bit é muito mais rápido que o Chrome e Math.flooré terrivelmente lento ... quase não deve ser usado, eu diria.
vsync

Para manter os comentários atualizados, no Fx atual, eles são rápidos e quase iguais. Não que seja provável que seja um gargalo, em primeiro lugar, em relação ao código em torno ...
FireFly

14

Dica de loop I

Você pode salvar um 1caractere ao fazer um loop alterando o ida última vez em que foi usado:

//not so god
for(i=0;i<3;i++){
  alert(i);
}

//best
for(i=0;i<3;){
  alert(i++);
}

Nota: também funciona --(mas modifique o loop de acordo para evitar loop infinito)


Dica de loop II

Existem certos cenários em que você pode salvar um personagem jogando com o operador e valores incrementais:

for(i=0;i++<9;)
for(i=0;++i<10;)

Nota: você precisa prestar atenção quando, por exemplo 0 to -1. e 9 to 10, 99 to 100, então brinque até encontrar uma maneira de salvar o personagem


13

Use em ^vez de !=ou ==ao comparar com um número inteiro

//x!=3?a:b
  x^3?a:b

//x==3?a:b
  x^3?b:a

Substituir chamadas para funções matemáticas internas por expressões mais curtas

//Math.ceil(n)
  n%1?-~n:n

//Math.floor(n)
  ~~n
  0|n

//Math.abs(n)
  n<0?-n:n

//Math.round(n)
  n+.5|0

//Math.min(x,y)
  x<y?x:y

//Math.max(x,y)
  y<x?x:y

2
Como alternativa, você pode simplesmente usar em -vez de!= para números inteiros; Por exemplo, n!=1?a:bseria equivalente an-1?a:b
vrugtehagel

10

Algo digno de nota é que você pode usar uma string no lugar de zero em alguns casos para salvar alguns bytes aqui e ali em loops:

s='';for(i=0;i++<9;)s+=i
for(i=s='';i++<9;)s+=i
// s="123456789", i=10

1
Eu tentei "" ++ no console antes imaginando se funcionaria, é claro que ele deve estar em uma variável primeiro. Obrigado!
Vartan

10

Muito simples, mesmo assim, ninguém havia mencionado.

Se você estiver usando Math.min()ou Math.max()puder salvar 6 caracteres, faça o seguinte:

Math.min(a,b)  // 13 chars
a<b?a:b        //  7 chars

Math.max(a,b)
a>b?a:b

10

Arredondamento

Eu sei que alternativas Math.floor()foram postadas, mas e as outras?

Pavimentação:

Math.floor(x) //before
0|x           //after

Arredondamento:

Math.round(x) //before
0|x+.5        //after

Teto:

Math.ceil(x) //before
x%1?-~x:x    //after - credits to @Tomas Langkaas

1
Observe que 0|x+1basta adicionar 1 se o número do qual você deseja encontrar o teto já for um número inteiro. Uma alternativa (principalmente) segura é 0|x+1-1e9, mas isso é apenas três bytes mais curto.
ETHproductions

@ETHproductions não quer dizer 0|x+1-1e-9?
Mama Fun Roll

Opa, sim. Obrigado por apontar isso. (Por alguma razão, eu não posso fazer @ (seu nome de usuário) ...)
ETHproductions

Provavelmente porque os meus caracteres de nome de usuário são de cabeça para baixo :)
Mama Fun rolo

1
Para teto, x%1?-~x:x(9 caracteres) é uma alternativa melhor. No entanto, como as alternativas de piso 0|xe ~~x, ele só funciona para números positivos.
Tomas Langkaas

9

Nos casos em que você está usando o operador ternário para escolher entre dois números , e o condicional é um booleano ou um número 1 or 0 , você pode executar operações matemáticas:

(x ? num1 : num2) conclusions:

    1)if num1 equals num2, there ARE savings
    2)if num1 is (+1) or (-1) than num2, there ARE savings
    3)if either num1 or num2 equals to 0, there ARE savings
    4)it is MORE LIKELY to find greater savings on num1>num2 instead of num1<num2
    5)in method (*A) and (*B), savings are NOT GUARANTEED

    a)num1>num2
        i)(num1==(num2+1))
            ex1: (x?5:4) to (x+4)
            ex2: (x?8:7) to (x+7)
        ii)num2==0
            ex1: (x?3:0) to (x*3)
            ex2: (x?7:0) to (x*7)
        iii)
            (*A) or (*B) //one might be shorter

    b)num1<num2
        i)((num1+1)==num2)
            ex1: (x?4:5) to (5-x)
            ex2: (x?7:8) to (8-x)
        ii)num1==0
            ex1: (x?0:3) to (!x*3)
            ex2: (x?0:7) to (!x*7)
        iii)
            (*A) or (*B) //one might be shorter

    c)num1==num2
        i)
            ex1: (x?5:5) to (5)
            ex2: (x?-3:-3) to (-3)

    (*A) use ((x*(num1-num2))+num2)
        ex1: (x?8:4)   to ((x*4)+4)
        ex2: (x?4:8)   to ((x*-4)+8)

        ex3: (x?6:-4)  to ((x*10)-4)
        ex4: (x?-4:6)  to ((x*-10)+6)

        ex5: (x?4:-6)  to ((x*10)-6)
        ex6: (x?-6:4)  to ((x*-10)+4)

        ex7: (x?-5:-9) to ((x*4)-9)
        ex8: (x?-9:-5) to ((x*-4)-5)

    (*B) use ((!x*(num2-num1))+num1)
        ex1: (x?8:4)   to ((!x*-4)+8)
        ex2: (x?4:8)   to ((!x*4)+4)

        ex3: (x?6:-4)  to ((!x*-10)+6)
        ex4: (x?-4:6)  to ((!x*10)-4))

        ex5: (x?4:-6)  to ((!x*-10)+4)
        ex6: (x?-6:4)  to ((!x*10)-6)

        ex7: (x?-5:-9) to ((!x*-4)-5)
        ex8: (x?-9:-5) to ((!x*4)-9)

Nota: Além disso, você precisará remover o desnecessário 0-, +0, +-etc.

Nota 2: existe um caso isolado em que (x) !== (x?1:0), como xdeve ser, typeof === "number"para que funcione. No entanto, no caso de(-x) funcionar muito bem.

Nota 3: Caso não encontre economia, basta usar o antigo(x?y:z)

Anteriormente, eu pensava que o método B nunca poderia vencer A, no entanto, existem exceções:

(x?97:100) //original

(-3*x+100)
(3*!x+97)

Criei um projeto no github que simplifica para nós ( demonstração do jsFiddle )


@ ajax333221 void 0(não é uma função, mas uma palavra-chave) não é um valor, simplesmente retorna undefined.
Camilo Martin

@CamiloMartin você está certo, agora também vejo o ponto nesta resposta, mas adeve ser 1 ou 0 para que ele funcione
ajax333221

@ ajax333221 Sim, na verdade, a coisa engraçada sobre o código de golfe para mim é que a maioria dos melhores truques funciona apenas para aquela coisa em particular que você está fazendo, e é tão inteligente encontrar um desses casos de canto com soluções de canto: D maneira, você não tem que excluir comentários ...
Camilo Martin

9

tl; dr: use os recursos do ES6!

Funções de seta

Doc: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/arrow_functions
Exemplo:

s = x => x*x
// s = function (x) {
//   return x * x;
// }

As funções de seta já foram mencionadas em 13 de outubro de 13 às 15:42 . Mas isso for.. ofé legal. Mesmo menor do que for each.. in.
Manatwork

2
A sintaxe de compreensão da matriz parece estar errada. De acordo com a documentação deve ser como em Python: b = [s(x) for (x of a)].
Manatwork

@manatwork As amostras acima funcionam bem no REPL de Traceur
Florent

Nenhuma idéia sobre o Traceur, mas você mencionou o ECMAScript e apontou para a documentação do Mozilla. E a compreensão da matriz em nenhuma delas parece com a que você escreveu.
manatwork

1
As compreensões de matriz foram realmente realizadas no meio.
Isiah Meadows

9

Literais de abuso

A amostra recente: verifique se "c"está em maiúscula ou minúscula, não importa se não está em letra

"c"<{} // returns false, lower case
"C"<{} // returns true, upper case

3
Como é que isso funciona?
Vacas quack

2
@Cowsquack String({})"[object Object]".
Dennis

8

Como comparar um número com a ajuda de como os números se transformam em booleanos:

Se você deseja verificar se algo é igual a um número positivo , pode subtrair esse valor e reverter o que estava dentro dos blocos ife else:

//simplified examples:
x==3?"y":"n"; <- 13 Chars
x-3?"n":"y"; <- 12 Chars

//expanded examples:
if(x==3){
    yes();
}else{
    no();
}

if(x-3){
    no();
}else{
    yes();
}

E caso você queira comparar com um número negativo (* diferente de -1), basta adicionar esse número em vez de subtrair.

* bem, você certamente pode usar x.indexOf(y) + 1, mas no caso especial de -1você ter a oportunidade de usá-lo ~x.indexOf(y).


8

Use o recurso "fechamento de expressão" fora do padrão da Mozilla para salvar muitos caracteres em um script que só precisa funcionar nos mecanismos SpiderMonkey / Firefox ou Rhino. Por exemplo,

function foo(){return bar}

torna-se

function foo()bar

Veja a página Estouro de pilha para mais truques.


2
Isso não é Javascript. Essa é uma estação espacial !!!
Thomas Eding

1
ECMAScript 6 para o resgate! ->bar
Ry-

5
ECMAScript 6:, let foo = () => bar;ironicamente mais curto que o código de golfe acima.
Isiah Meadows

1
ECMAScript 6:, foo=_=>barainda mais curto.
ETHproductions

esse link está quebrado.
Cyoce 11/02



8

Transformando em um booleano :

if(b){b=true}else{b=false}
b=b?true:false;
b=b?!0:!1;
b=!!b;

Nota: Isso muda 0, "", false, null, undefinede NaNpara false(tudo mais para true)

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.