Советы по игре в гольф на JavaScript


133

Какие общие советы у вас есть для игры в гольф на JavaScript? Я ищу идеи, которые могут быть применены к проблемам с гольфом в коде, которые, по крайней мере, несколько специфичны для JavaScript (например, «удалить комментарии» - это не ответ).

Примечание. См. Также Советы по игре в гольф в ECMAScript 6 и выше.


Мне было действительно интересно, разрешено ли помещать переменные в глобальные (сохраняет var)? И должен ли гольф-код JavaScript быть функцией или выводить что-то напрямую? Я искренне думаю, что это может иметь большое значение.
— pimvdb

1
@primvdb: Это разрешено, но вы должны быть осторожны, потому что это может вызвать побочные эффекты, если функция вызывается несколько раз и манипулирует глобальными переменными или является рекурсивной функцией.
— mellamokb

Ответы:


108

Fancy For Loops

Вы можете использовать стандарт для цикла нестандартными способами

for ( a; b; c )

по существу эквивалентно:

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

так что хороший трюк - написать код с whileциклом, а затем разбить его на a,b,cчасти в forцикле.

Несколько примеров, которые я написал :

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);

Цепи ваши сеттеры

Если вы инициализируете или сбрасываете несколько значений, объедините их во все переменные, которые в нем нуждаются:

a=b=1;

Неявное кастинг

Не проверяйте свои типы, просто используйте их как есть. parseInt()стоит 10персонажей. Если вам нужно изгнать из строки, будьте изобретательны:

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;

Избегайте точек с запятой

JavaScript имеет автоматическую вставку точек с запятой. Используйте это часто и хорошо.

Однострочники

Сохраните в скобках, запихивая как можно больше в отдельные строки или параметры:

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

Операторы приращения / убывания

a = a - 1;
foo(a);

а также

foo(a);
a = a - 1;

может быть легко переписан как

foo(--a);

а также

foo(a--);

соответственно.

Использовать thisили selfвместо windowв глобальном контексте

Само собой разумеющееся 2 символа сбережений.

Используйте скобочные обозначения для повторного доступа к свойствам

Это определенно баланс между длиной имени свойства и количеством обращений. Вместо того, чтобы a.longFunctionName()дважды вызывать с точечной нотацией, короче сохранить имя и вызвать функцию через скобочную нотацию:

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

vs-

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

это особенно эффективно с такими функциями, document.getElementByIdкоторые можно уменьшить до d[e].

Примечание:

В скобках обозначены 6 + name.lengthсимволы в первый раз. Каждый последующий доступ имеет стоимость 3символов.

Для точечной нотации все обращения стоят name.length + 1(+1 для .) символов.

Используйте этот метод, если 6 + name.length + (3 * (accesses - 1)) < accesses * (name.length + 1).

len = длина имени свойства
i = минимальный доступ для использования

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

Количество доступов также может охватывать несколько объектов. Если вы используете .length4 или более раз для разных массивов, вы можете использовать одну и ту же переменную, содержащую строку 'length'.


5
c = ~~a-~~bдолжно быть c = ~~a+~~b. Кроме того, вы можете неявно приводить к целому числу |0, например, используя Math.random()*6|0.
— mellamokb

7
Дешевле принудительно привести строку к числу с помощью оператора унарный плюс. Если aи bявляются строками, вы можете сделать, +a+bчтобы преобразовать в число и добавить их.
— Питер Олсон

8
Клянусь, я собираюсь использовать d- -bв своем коде когда-нибудь ...
— Джон Дворжак

4
+ a + b не работает (по крайней мере, на моем ...) // a = "1", b = "1", + a + b // выдает "11"
— imma

2
Для «Использовать доступ к массиву для повторных вызовов функций», если вы используете функцию более двух раз на одном и том же объекте , то, что немного короче, так это назначить функцию новому члену, какa.f=a.longfunctionname;a.f(b);a.f(c);a.f(d)
— Martin Ender

131

Разделение по номерам для сохранения кавычек:

"alpha,bravo,charlie".split(",") // before
"alpha0bravo0charlie".split(0)   // after

2
Это работает, и я использовал его для нескольких цифр.
— Isiah Meadows

12
Lol это на самом деле довольно креативно
— NiCk Newman

9
в ES6 это больше не имеет значения, вы можете просто сделать.split`...`
— Дэвид Арчибальд

"alpha,bravo,charlie".split`,`
— Камиль Келчевски

56

Используйте оператор запятой, чтобы избежать скобок (также относится к C ):

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

Вместо

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

который на один символ длиннее.


2
Нужна ли точка с запятой в конце первого образца?
— WJL

4
@wjlafrance: Это не требуется, только если он находится в конце строки.
— mellamokb

48

Короче генерация случайных чисел

Если вам нужен случайный логический ( 0или 1):

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

Если вам нужно случайное целое число 0 <= n < 1337:

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

Это работает, потому что a Dateхранится внутри JavaScript в виде количества миллисекунд с начала эпохи, поэтому на new Dateнего навязывают, 123somebignumber456когда вы пытаетесь выполнить с ним целочисленную математику.

Конечно, эти «случайные» числа на самом деле не будут такими случайными, особенно если вы вызываете их несколько раз подряд, так что имейте это в виду.


1
Просто запомнили этот ответ, читая Больше лжецов, которым программисты верят во время : «21. Если вы создадите два объекта даты рядом друг с другом, они будут представлять одно и то же время. (фантастический генератор Гейзенбаг) » .
— Себастьян Симон

39

Вы можете использовать объектную буквальную форму get / set, чтобы избежать использования ключевого слова 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)

часть получения / установки была действительно полезна. thx
— gion_13

1
На самом деле, даже лучше использовать объектный метод, если вы используете его <= 2 раза. С другой стороны, функции стрелок намного лучше сокращают символы, поскольку они служат почти той же цели, а классы редко используются в коде игры в гольф.
— Isiah Meadows

если поддержка важна, функции стрелок не поддерживаются в FX. ie11
— Джим Вольф

35

Это менее известный и менее используемый, но может быть впечатляющим, если используется в правильной ситуации. Рассмотрим функцию, которая не принимает аргументов и всегда возвращает другое число при вызове, и возвращенное число будет использовано в вычислении:

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

Обычно вы можете сократить эту функцию, используя однобуквенное имя переменной:

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];

Лучший способ уменьшить длину - злоупотреблять valueOf, что дает вам экономию 2 символов за вызов. Полезно, если вы вызываете функцию более 5 раз:

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
Или, вы можете сделать это так: let a=[5,6,7,8,9,10,11,12].map(x=>x*Math.random()|0)или let a=Array(7).map((_,i)=>i*Math.random()|0+5)36 или 42 байта, соответственно.
— Исия Медоус

Можно ли заменить r()или сделать его короче?
— NiCk Newman

3
r={valueOf:Math.random}Это просто гений: D
— ETHproductions

1
@Isiah, ну да, теперь ты можешь это сделать :-D
— Энди Э,

32

Использование преимуществ операторов короткого замыкания

Вместо длинных ifоператоров или использования троичных операторов вы можете использовать &&и ||сократить свой код. Например:

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

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

может стать

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

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

||Оператор часто используется таким образом , для установки по умолчанию:

evt = evt || window.event;

Это так же, как написание

if (!evt)
    evt = window.event;

Создание повторяющихся строк с использованием массива

Если вы хотите инициализировать длинную строку определенного символа, вы можете сделать это, создав массив длиной n + 1 , где n - количество повторений символа:

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

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

Чем больше строка, тем больше экономия.

Разбор чисел

Используйте +и ~операторы вместо parseFloat()или parseInt()при объединении строкового типа, который является просто числом, к числовому типу:

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()

Будьте осторожны, другие типы могут объединяться с этими операторами (например, trueстать 1) пустой строкой или строкой, содержащей только пробел 0. Это может быть полезно в определенных обстоятельствах, однако.


6
+1 за создание повторяющихся строк с использованием Array - не думал об этом.
— mellamokb

4
Для создания повторяющихся строк в ES6 вы можете использоватьstr.repeat(count)
— Oriol

26

Вставить инициализацию переменной в вызов prompt () для получения пользовательского ввода

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

Вместо того, чтобы использовать

n=prompt();i=5;

Как побочный эффект, он отображает входное значение в окне подсказки, сохраняя при этом 1 символ.


12
Это также может быть применено к любой функции, которая не принимает аргументы.
— Кейси Чу

3
Даже когда функция принимает аргументы, это может быть полезно, как [1,2,3].join('',i=5)в случаях, когда она сохраняет пару фигурных скобок.
— DocMax

3
@DocMax: Вы можете использовать оператор запятой для этого - i=5,[1,2,3].join().
— Конрад Боровски

@GlitchMr: Я мог бы, но это не спасает никаких символов. Я согласен, что большую часть времени это будет чище. Я думаю, что все еще могут быть случаи, когда мой заказ может сохранить символ, хотя я не могу придумать его в данный момент (и я вполне могу ошибаться).
— DocMax

@DocMax Только если вы используете ASI.
— Исия Медоус

24

Объединить вложенные в петли:

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

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

Пример с разными значениями для 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)

(Я отредактировал) незначительную опечатку, но очень умно! Обратите внимание, что это будет работать только на вложенных циклах одинаковой длины (если я не ошибаюсь).
— Камило Мартин

1
@CamiloMartin Нет, циклы не обязательно должны быть одинаковой длины. Полученное число итераций равно, i*jи операторы деления / модуля извлекают отдельные значения iи j.
— тихая мята

@ user113215 Ты прав, офигенно! :) Я отредактировал ответ, чтобы включить пример.
— Камило Мартин

23

Юникод ярлыки

Если вы используете чертовски встроенную собственность на большом соревновании по гольфу, вы можете присвоить псевдониму каждую собственность эквиваленту одного символа:

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

После выполнения кода выше вы можете использовать его следующим образом:
"foo".Č(/.*/,'bar') // replaces foo with bar

Это стоит 118 байт, поэтому в некоторых ситуациях это может оказаться бесполезным.

Это может зависеть от браузера, и я не уверен, что он короче with(Array){join(foo),...}или определяет переменные как используемые свойства, with(Array){j=join,m=map...}но все же стоит упомянуть.

    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         

Я использую Google Chrome, и все они дают неопределенные.
— SuperJedi224

Это должно быть очень специфично для Firefox. Приносим извинения за неудобства.
— bebe

Почему это все специальные символы? Почему бы просто не использовать печатный ASCII? (легче набрать, надежнее и всего 1 байт для игры в гольф)
— Cyoce

Это на самом деле не работает, Mathпотому что у него нет .prototypeатрибута. Однако, удалив Math, мне удалось воспроизвести это до 114-байтового фрагмента, который назначает их всем однобайтовым буквам. Вы можете найти это здесь .
— ETHproductions

1
Вы можете также гольф мое решение до 106 байт за счет перемещения всех этих свойств в диапазоне À- ÿ, который еще один байт каждый в ISO-8859-1 кодирования (который поддерживает JS). В Firefox 50 это, к сожалению, включает .localeCompareметод ×, но обычно это не должно быть проблемой. источник
— ETHproductions

22

Преобразование whileцикла в forцикл часто эквивалентно:

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

Но вторая форма может иметь объединенную инициализацию переменной:

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

Обратите внимание, что вторая форма на один символ короче первой.


6
Или, что еще лучше, просто используйте петли. На самом деле, ни один случай, когда использование цикла for приводит к большему коду, насколько я знаю.
— Исия Медоус

22

Исключение злоупотребляет

если строковые / символьные литералы запрещены, вы можете использовать блок try catch:

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

теперь strравняется"something"

если нужно больше строк, вы можете связать их числом (например, нулями)

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

теперь arrравняется["something", "foo", "bar", " is not defined"]


18

Если вы инициализируете переменную 1в каждой итерации цикла (например, сбрасываете переменную во внешнем цикле для внутреннего цикла), как показано ниже (из моего ответа на этот вопрос ):

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

Поскольку результатом условия like j++<=nявляется 1всякий раз, когда оно имеет значение true, вы можете просто назначить условие непосредственно переменной (поскольку, когда оно становится ложным, цикл прекращает выполнение и больше не имеет значения):

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

Обычно вы можете сохранить 2 символа, используя этот метод. С уважением к @ugorenидее в комментариях к этому ответу.


В качестве другого примера я также применил этот трюк к своему ответу здесь с выражением w=r=++c<S.lengthво внешнем цикле for, сохранив всего 4 символа.


18

Если вы можете принять специальные сценарии Spidermonkey (на данный момент), вы можете использовать функции стрелок ECMAScript 6 . Вместо написания кода, как показано ниже.

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

Вы можете сократить это, как это.

a.map(x=>x*2)

17

Если вам нужно проверить NaN, не используйте isNaN(x), но используйте x!=x, который короче и также работает.

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

Обратите внимание, что это работает только если typeof(x) === "number"; если это строка, например, isNaN("string")возвращает true, но "string" != "string"возвращает false. Спасибо Cyoce за указание на это!


2
Это гениальное использование этой причуды. +1
— ETHпродукция

Предупреждение: они не всегда эквивалентны: isNaN("string")возвращается true, тогда как "string"!="string"возвращается false(очевидно)
— Cyoce

@Cyoce Хорошо, спасибо! Я отредактировал свой ответ.
— ProgramFOX

Во многих случаях вы можете даже пойти if(!x){, если вы обнаруживаете NaNявно.
— Hohmannfan

1
Приведение xк числу, +x!=+xделает его эквивалентным isNaN(x), но все же на 2 символа короче. Затем +"string"!=+"string"возвращает истину.
— Томас Лангкаас

15

Сумма массива / продукт / частное

ES5 : 17 байт

eval(a.join('+'))

ES6 : 15 байт

eval(a.join`+`)

Конечно, вы можете поменять их +на что угодно, например, *на продукт или /частное.


14

Используйте побитовую операцию, чтобы округлить число до нуля:

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

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

(Источник: Случайная игра в кости )

Приоритет оператора определяет, что будет короче в вашей программе.


2
Это также может быть использовано для коалесценции строки ввода в целое число, то есть n=prompt()|0.
— mellamokb

1
побитовое тоже очень быстро по сравнению с math.floor: jsperf.com/floor-vs-bitwise
— vsync

@vsync: странно. Я получаю math.floor примерно в два раза быстрее, чем побитовый на Chrome 11.0.696.77.
— mellamokb

очень странно. для меня они оба более или менее одинаковые скорости и супер быстрые в Chrome, но в FF побитовая скорость намного быстрее, чем Chrome, и Math.floorужасно медленная .. почти не следует использовать, я бы сказал.
— vsync

Чтобы поддерживать актуальность комментариев, в текущем Fx они оба быстрые и примерно одинаковые. Не то чтобы это скорее всего было узкое место, по сравнению с окружающим кодом ...
— FireFly

14

Looping Tip I

Вы можете сохранить 1символ при зацикливании, изменив iна последний использованный:

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

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

Примечание: работает --также (но измените цикл соответственно, чтобы избежать бесконечного цикла)


Looping Tip II

Есть определенные сценарии, в которых вы можете сохранить один символ, играя с инкрементным оператором и значениями:

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

Примечание: нужно обратить внимание, когда, например 0 to -1. и 9 to 10, 99 to 100, так что поиграйте, пока не найдете способ сохранить персонажа


13

Использовать ^вместо !=или ==при сравнении с целым числом

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

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

Замените вызовы встроенных математических функций более короткими выражениями.

//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
Кроме того, вы можете просто использовать -вместо !=целых чисел; Например, n!=1?a:bбудет эквивалентноn-1?a:b
— vrugtehagel

10

Стоит отметить, что в некоторых случаях вы можете использовать строку вместо нуля, чтобы сохранить несколько байтов здесь и там в циклах:

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

1
Я пытался "" ++ в консоли ранее, задаваясь вопросом, будет ли он работать, конечно, сначала он должен быть в переменной. Спасибо!
— Вартан

10

Очень простой, даже так, никто не упомянул об этом.

Если вы используете Math.min()или Math.max()можете сохранить 6 символов, сделав это:

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

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

10

округление

Я знаю, что альтернативы Math.floor()были опубликованы, но как насчет других?

Напольное покрытие:

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

Округление:

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

Потолок:

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

1
Обратите внимание, что 0|x+1просто добавляется 1, если число, которое вы хотите найти, уже является целым числом. (В основном) безопасная альтернатива есть 0|x+1-1e9, но она всего на три байта короче.
— ETHproductions

@ETHproductions разве ты не имеешь ввиду 0|x+1-1e-9?
— Mama Fun Roll

Ой, да. Спасибо что подметил это. (По какой-то причине я не могу сделать @ (ваше имя пользователя) ...)
— ETHproductions

Вероятно, потому что мои символы в логине перевернуты вверх ногами
— Mama Fun Roll

1
Для потолка x%1?-~x:x(9 символов) - лучшая альтернатива. Однако, как альтернативы настила 0|xи ~~x, это работает только для положительных чисел.
— Томас Лангкаас

9

В тех случаях, когда вы используете троичный оператор для выбора между двумя числами , а условным условием является либо логическое значение, либо число 1 or 0 , вы можете вместо этого выполнять математические операции:

(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)

Примечание: В дополнение к этому, вам нужно будет удалить ненужные 0-, +0, и +-т.д.

Примечание 2: есть единичный случай, когда (x) !== (x?1:0), как это xдолжно быть, typeof === "number"для его работы. Однако в случае с (-x)этим все работает просто отлично.

Примечание 3: Если вы не нашли сбережения, просто используйте первый(x?y:z)

Ранее я думал, что метод B никогда не сможет победить A, однако существуют исключения:

(x?97:100) //original

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

Я создал проект GitHub, который делает упрощение для нас ( демонстрация jsFiddle )


@ ajax333221 void 0(это не функция, а ключевое слово) не является значением, оно просто возвращает undefined.
— Камило Мартин

@CamiloMartin вы правы, и теперь я вижу смысл в этом ответе, однако aдля его работы должно быть либо 1, либо 0
— ajax333221

@ ajax333221 Да, на самом деле забавная вещь в игре в гольф кода состоит в том, что большинство лучших трюков работают только для той конкретной вещи, которую вы делаете, и каждый чувствует себя настолько умным, чтобы найти один из этих угловых случаев с угловыми решениями: D Кстати, вам не нужно удалять комментарии ...
— Камило Мартин

9

tl; dr: использовать функции ES6!

Функции стрелок

Документ: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/arrow_functions
Пример:

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

Функции стрелок уже упоминались 13 октября 13 в 15:42 . Но это for.. ofэто круто. Даже короче for each.. in.
— manatwork

2
Синтаксис понимания массива кажется неправильным. Согласно документации , должно быть , как в Python: b = [s(x) for (x of a)].
— manatwork

@manatwork Приведенные выше примеры прекрасно работают в REPL Traceur
— Флоран

Понятия не имею о Traceur, но вы упомянули ECMAScript и указали на документацию Mozilla. И массив массивов ни в одном из них не выглядит так, как вы написали.
— manatwork

1
Массивы были на самом деле вытащены на полпути.
— Исия Медоуз

9

Злоупотреблять литералами

Недавний пример: проверьте, "c"есть ли прописные или строчные буквы, не имеет значения, если не буква

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

3
Как это работает?
— Kritixi Lithos

2
@ Cowsquack String({})дает "[object Object]".
— Деннис

8

Как сравнить число с помощью того, как числа превращаются в логические значения:

Если вы собираетесь проверить , если что - то равно положительное число , вы можете вычесть эту сумму и обратную , что было внутри ifи 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();
}

И в случае, если вы хотите сравнить с отрицательным числом (* отличным от -1), вам просто нужно добавить это число вместо вычитания.

* ну, вы, конечно, можете использовать x.indexOf(y) + 1, но в особом случае у -1вас есть возможность использовать ~x.indexOf(y)вместо этого.


8

Используйте нестандартную функцию «закрытия выражений» в Mozilla, чтобы сохранить множество символов в скрипте, который должен работать только в движках SpiderMonkey / Firefox или Rhino. Например,

function foo(){return bar}

становится

function foo()bar

См. Страницу переполнения стека для большего количества таких уловок.


2
Это не Javascript. Это космическая станция !!!
— Томас Эдинг

1
ECMAScript 6 на помощь! ->bar
— Ry-

5
ECMAScript 6: let foo = () => bar;иронически короче, чем приведенный выше код для игры в гольф.
— Исия Медоус

1
ECMAScript 6: foo=_=>barеще короче.
— ETHproductions

эта ссылка не работает.
— Cyoce



8

Преобразование в логическое значение :

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

Примечание: Это изменение 0, "", false, null, undefinedи NaNк false(все остальное true)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.