Pull to refresh

Comments 28

Ну почему же, это разве не годится для обфускации?

не понял что это за херота

if (command === 'm') ...

if (command === 'i') ...

if (command === 'd') ...

if ((command === 'j') ...

и тд

разве нельзя перейти к описанию синтаксиса в js через объект

obj = {

'm': {

handler: function() { ... },

...},

'i":

{

handler: function() { ... },

...},

...

}

и соответственно if(obj[command]?.handler) obj[command].handler();

я вообще-то не спец в js

Вполне можно. Я сразу после листинга кода указал, что есть 3 варианта: if+else/switch/hashmap. Но так или иначе, пришлось бы возвращаться к варианту выбора из 4ех, так как это более краткий вариант. Можно даже сразу писать в краткой форме `{i() {...}. d() {...}}` и это-все равно слишком громоздко

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

Вы же оптимизировали(минимизировали) по размеру, а не по скорости

Размер и скорость обычно антагонисты на типовых процессорах

Всегда можно проверить на практике:

simple_assembler=p=>{
i=0,m={}
c=0
o={m(){m[f]=+s==s?+s:m[s]},d(){m[f]--},i(){m[f]++},j(){(+f||m[f])&&(c=+s)}}
while(p[i]){
c=1,[[w],f,s]=p[i].split` `
o[w]()
i+=c}return m}

Сократил вариант с хэш-мапой. Итого: 173 символа против 146.

Думаю, если посижу подольше, то смогу выгрызть еще несколько символов, но точно не смогу догнать вариант с сокращениями через явные проверки.

а, например, не лишняя строка c=0?

Вы правы, ее можно безболезненно убрать, так как необъявленные переменные без strict-мода записываются сразу в глобальный скоуп. Но погоды это особо не делает (-4 символа)

не знаю как вы считаете символы, но вот ещё вариант - это 148 без рекурсии

```

simple_assembler=p=>(m={},{x(i){v=z=>+z==z?+z:m[z];for(;l=p[i++];w=='m'?m[f]=v(s):w!='j'?m[f]+=w=='i'||-1:v(f)?i+=s-1:0)[w,f,s]=l.split }}.x(0),m)

```

simple_assembler([
"m a 1",
"i a"
])
{a: 2}

а ваш вариант, который обозначен 140 работает неправильно
```

simple_assembler=p=>(m={},x=i=>p[[[w],f,s]=p[i].split` `,i+=w!='j'?(m[f]=v=='m'?+s==s?+s:m[s]:m[f]+(w=='i'||-1),1):+f||m[f]?+s:1]?x(i):m)(0)

```

simple_assembler([
"m a 1",
"i a"
])
{a: NaN}

Действительно, спасибо за то что заметили, в листинге опечатка: v спутана с w. При данном изменении тесты на целевой платформе проходятся все, кроме тех, где валится из-за рекурсии

Я думаю этот код будет лучше 137 символов и без рекурсий

simple_assembler=p=>(i=>{for(m={};l=p[i++];w=='m'?m[f]=+s==s?+s:m[s]:w!='j'?m[f]+=w=='i'||-1:+f||m[f]?i+=s-1:0)[w,f,s]=l.split` `})(0)||m

Я вообще-то не эксперт по js

а вот этот код 136 символов и без рекурсии

simple_assembler=p=>(i=>{for(m={};l=p[i++];t=m[f],w!='j'?m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w]:+f||t?i+=s-1:0)[w,f,s]=l.split })(0)||m

Если ещё попилить - то наверно можно и сократить

Я не эксперт в js - можно попробовать спросить у фронтендеров, но я думаю они не будут тратить на это своё время

данная версия не проходит тесты на CodeWars - вы решаете немного другую задачу по-моему

Я не знаю где это и что это

Я просто переписал код автора и подготовил свой тест...по которому получилось что код автора на 140 неработосрособный

Автор явно не сформулировал постановку задачи....подозреваю что там разница в синтаксисе комманд и, соответственно, должно быть [[w],f,s]=p[i].split` `...я уже писал об этом....данный вариант для набора команд midj, а не mov inc dec jnz

Рекурсивная версия пока получается только 139

simple_assembler=p=>(m={},x=i=>p[i]?x(([w,f,s]=p[i].split ,t=m[f],w=='j'?+f||t?i+=s-1:0:m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w],i+1)):m)(0)

Дальнейшие попытки выноса переменных, перестановки веток условий либо не дали каких либо улучшений, либо наоборот увеличивали код. На данный момент мне не удалось найти способов еще ужать код. Возможно это удастся кому-то из читателей. Лично я получил много удовольствия от того, как когда, казалось бы, сжать код больше нельзя, удавалось-таки вырвать еще пару байтов. Думаю, такая игра в минификатор - вполне забавный досуг, позволяющий взглянуть с другой стороны на язык, с которым работаешь каждый день.

136 без рекурсии

simple_assembler=p=>(i=>{for(m={};l=p[i++];t=m[f],w!='j'?m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w]:+f||t?i+=s-1:0)[w,f,s]=l.split })(0)||m

Рекурсивная версия 139

simple_assembler=p=>(m={},x=i=>p[i]?x(([w,f,s]=p[i].split ,t=m[f],w=='j'?+f||t?i+=s-1:0:m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w],i+1)):m)(0)

Я не эксперт в js

Но мои комменты минусят, комменты автора плюсят - куда катится мир?

А вот и рекурсия 138

simple_assembler=p=>(m={},x=i=>p[i]?x(([w,f,s]=p[i].split ,t=m[f],i+=w=='j'?+f||t?+s:1:(m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w],1))):m)(0)

можно её ещё попилить - рекурсиии обычно получаются более компактными по коду

Немного поправлюсь

Я в начале не вкурил зачем [[w],f,s]=p[i].split` ` потом понял

Тут есть ещё особенность jz бывают с относительной адресацией и с абсолюстной - в примере автора похоже на относительную адресацию

с учетом этого

нерекурсивный вариант 138

simple_assembler=p=>(i=>{for(m={};l=p[i++];t=m[f],w=='j'?+f||t?i+=s-1:0:m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w])[[w],f,s]=l.split })(0)||m

рекурсивный 139
simple_assembler=p=>(m={},x=i=>p[i]?x(i+([[w],f,s]=p[i].split ,t=m[f],w=='j'?+f||t?+s:1:(m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w],1))):m)(0)

если jz использует абсолютную адресацию, то

нерекурсивный вариант 136

simple_assembler=p=>(i=>{for(m={};l=p[i++];t=m[f],w=='j'?+f||t?i=+s:0:m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w])[[w],f,s]=l.split })(0)||m

рекурсивный 139

simple_assembler=p=>(m={},x=i=>p[i]?x(([[w],f,s]=p[i++].split ,t=m[f],w=='j'?+f||t?+s:i:(m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w],i))):m)(0)

Слегка переписал рекурсивные варианты

Если в jz относительная адресация, то как и было 139

simple_assembler=p=>(x=i=>p[j]?x([[w],f,s]=p[j++].split` `,t=m[f],w=='j'?+f||t?j+=s-1:0:m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w]):m)(m={},j=0)

Если в jz абсолютная адресация, то стало 137

simple_assembler=p=>(x=i=>p[j]?x([[w],f,s]=p[j++].split` `,t=m[f],w=='j'?+f||t?j=+s:0:m[f]={m:+s==s?+s:m[s],i:t+1,d:t-1}[w]):m)(m={},j=0)

Это все с использованием [[w],f,s]

Если использовать [w,f,s] для набора команд midj , то соответственно размеры -2

Очень круто, рад что кому-то тоже было интересно поломать голову над этим и у него получился результат даже лучше. Я свой код скоратил +- с вашими шагами и и получилось 140. На 1 символ больше чем у вас для полностью работающего варианта.

Насчет требований: я их обозначал, что условием является прохождением тестов задачи на CodeWars (ссылка на задачу есть в статье). Поэтому варианты без [] и абсолютным позиционированием не пройдут, но являются хорошим дополнением к задаче.

Версия на 131 символ.

Основана на основе кода автора статьи и комментариев dprotopopov, дополнительные оптимизации:

  • учтена способность ++ превращать пустую строку в целое число 0 (а не в NaN)

  • использована операция ?? чтобы более коротким образом читать из объекта с дефолтом

  • использована операция | вместо ||, которая удачно превращает undefined в 0

simple_assembler=p=>(i=>{for(m={};s=p[i++];x=m[a],o!='j'?m[a]={m:m[b]??+b,i:x+1,d:x-1}[o]:i+=+a|x?b-1:0)[[o],a,b]=s.split` `})``||m

https://www.codewars.com/kata/reviews/58e34fb383cbf8f077000ef9/groups/64172f8db4d31600018e237f

Браво. Очень красивые приемы, обязательно возьму их на вооружение. Век живи - век учись.

+undefined|21 // прям очень классно, что NaN при бинарной операции считается 0-ом
?? // немного в шоке, что до такой очевидной операции не догадался

Хоть вторую часть пиши по вашим комментариям, так как приемы меня прямо в восторг привели. И еще раз, крайне рад, что кто-то еще поигрался над этой "головоломкой".

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

Есть не только фишки языка, но и чисто математические формулы, например, a+=b+1 то же самое (если не учитывать взведение флага переноса на процессоре) что и a-=~b

Здорово

Я тоже подумывал о возможностм использования битовых операций, но не был уверен...просто не знаю всех фишек js

Та же лямда тоже не очень давно добавлена в js

Когда в js добавят еще сахара то и код наверно короче можно будет сделать

Можно еще попробовать попилить рекурсивную версию...обычно рекурсивные версии бывают более компактными по размеру кода...у меня это не получилось

Держите на 130

simple_assembler=p=>(i=>{for(m={};s=p[i++];x=m[a],o!='j'?m[a]={m:m[b]??+b,i:x+1,d:x-1}[o]:i+=a|x?b-1:0)[[o],a,b]=s.split` `})``||m

https://www.codewars.com/kata/reviews/58e34fb383cbf8f077000ef9/groups/642b6e556f55aa000124a14a

  • использована операция | вместо ||, которая удачно превращает undefined в 0

Все равно...у меня больше опыта...хоть я и не спец в js

Sign up to leave a comment.

Articles