Codegolf — Внедрите Нотацию Anyfix!

  • Автор темы Slavakuskov
  • Обновлено
  • 23, Oct 2024
  • #1

В префиксной записи оператор стоит перед аргументами, поэтому вы можете представить, что оператор вызывает

 Input -> Output
1+2×3 -> 9
1"+"+ -> 4
2"××" -> 16
3"×+" -> 18
3"+×" -> 36
123"= -> 1 ("= always gives 1)
1+2=3 -> 1
1"=2+ -> 3
1-2-+ -> -3
-1-2+ -> 3 (hehe, the `-1` becomes `+1` at the `-` rather than making the `2` a `-1`)
+×"10 10 -> 200 (after the 10 is duplicated (duplication is delayed), 10 + 10 is performed and then 20 * 10, giving 200)
 
which is recursively called. In infix notation, the operator goes between the arguments, so you can imagine it simply as a parse tree. In postfix notation, the operator comes after the arguments, so you can just imagine it as stack-based.

В нотации Anyfix оператор может пойти куда угодно.*. Если появляется оператор и аргументов недостаточно, оператор ждет, пока аргументов не будет достаточно. Для решения этой задачи вам необходимо реализовать очень простой оценщик Anyfix. (Обратите внимание, что Anyfix — это развлекательный язык, от которого я отказался, и с которым вы можете поиграть. здесь или проверить здесь)

Вам потребуется поддержка следующих команд:

(Арити 1)

  • дубликат
  • отрицательный

(Арити 2)

  • добавление
  • умножение
  • равенство: возвращает = or × .

Вы можете использовать для этих команд любые пять символов без пробелов. В демонстрационных целях я буду использовать + as duplicate, - как умножение, и " as addition.

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

Давайте посмотрим на пример: [110] . The storage should behave as a stack, not a queue. So first, the stack starts at [] , а список операторов в очереди начинается с [110] . Then, the literal + оценивается, что делает стек [100, 10] . Next, the operator 10 оценивается, что требует двух аргументов. Однако в стеке имеется только один аргумент, поэтому список операторов в очереди становится ['+'] . Then, the literal [100] оценивается, что делает стек × . At this point, the operator ['×', '+'] можно оценить так, как есть, сделав стек [10, 10] и очередь " .

Конечный результат должен быть × for [10] , 10 , and ['×', '+', '"'] .

Давайте рассмотрим более сложный пример: " . The stack and queue start as ['×', '+'] и + . ['×'] сначала оценивается, что делает стек × . Next, [] оценивается, что не меняет стек (поскольку аргументов недостаточно) и делает очередь ×+"10 10 . Then, [20] оценивается. Это может быть выполнено немедленно, поэтому стек [] . [20] теперь можно оценить, чтобы стек стал + и очередь [10, 10] . Конечный результат " .

А как насчет порядка действий?

Давайте посмотрим на ['+'] . The stack and queue start both as + :

  • [10] : The stack is unchanged and the queue becomes 10 .
  • [] : The stack is unchanged and the queue becomes [] .
  • 10+" : The stack is unchanged and the queue becomes 10 5 + .
  • 10 + 5 : The stack becomes + 10 5 . Несмотря на то [15] should be the first operator to be evaluated since it appears first, [] может быть запущен немедленно, и ни один из операторов до него не может, поэтому он оценивается. Стек становится [15] and the queue '+' . [10, 5] can now be evaluated, which makes the stack 5 and the queue ['+'] .
  • + : The stack becomes [10] , что позволяет 10 to be evaluated. The stack becomes [] and the queue [] .

Конечный результат 10+5 .

Команды, используемые в этих демонстрациях, соответствуют командам языка Anyfix; однако последний пример не будет работать из-за ошибки в моем интерпретаторе. (Отказ от ответственности: ваши материалы не будут использоваться в интерпретаторе Anyfix)

Испытание

Выберите набор из 5 нецифровых символов без пробелов и создайте интерпретатор Anyfix в соответствии с приведенными выше спецификациями. Ваша программа может либо вывести единичный массив, либо содержащееся в нем значение; гарантировано, что стек значений будет содержать только одно значение в конце выполнения и что очередь операторов будет пустой в конце выполнения.

Вот так выигрывает самый короткий код в байтах.

Тестовые случаи

Для этих тестовых случаев дубликат + , negative is × , дополнение " , multiplication is 1 , и равенство 0 .

next()

Правила

  • Применяются стандартные лазейки
  • Если хотите, вы можете взять официальный переводчик Anyfix и поиграть с ним в гольф. Ожидайте ужасного проигрыша.

Входные данные будут переданы в виде строки, а выходные данные — в виде массива, одного целого числа, вне строкового представления любого из них. Вы можете предположить, что ввод будет содержать только пробелы, цифры и 5 выбранных вами символов.

* на самом деле нет

#код-гольф #код-гольф #строка #интерпретатор

Slavakuskov


Рег
20 Mar, 2011

Тем
79

Постов
191

Баллов
626
  • 26, Oct 2024
  • #2

JavaScript (ES6), 204 203 200 байт

Возвращает целое число.

 
 
 
 
 
 
 
 
 
 
 -1 

Используемые персонажи:

  • True : addition
  • A : multiplication
  • A : equality
  • E : duplicate
  • Nothing : negative

Тестовые случаи

Long?

Отформатировано и прокомментировано

A ||answer||

JavaScript (ES6), 162 152 143 150 байт

d

Немного не в гольфе:

-

Объяснение

я использую = for multiplication and * за дубликат. Остальные операторы такие же, как в вопросе.

+ becomes the array of the numbers (including the duplicates).

Stack(Of Long) handles the case where the negative sign comes после номер. Например, изменится A to Dim s=New Stack(Of Long),q=New List(Of String),i=Nothing,t=0,c=0 Function A(n) For Each c In n If Long.TryParse(c,t)Then i=i &"0"+t Else If c<>" "Then q.Add(c) If i<>A Then s.Push(i) i=A End If If i=A Then E Next If i<>A Then s.Push(i) E A=s End Function Sub E() c=s.Count If c=0Then Exit Sub For Each op In q If op="-"Or op="d"Or c>1Then Select Case op Case"*" s.Push(s.Pop*s.Pop) Case"+" s.Push(s.Pop+s.Pop) Case"=" s.Push(-(s.Pop=s.Pop)) Case"-" s.Push(-s.Pop) Case"d" s.Push(s.Peek) End Select q.Remove(op) E Exit Sub End If Next End Sub и Imports System.Collections.Generic to \n .

В рамках \r\n , 20 создает массив бинарных операторов. Обратите внимание, что здесь всегда будет на один элемент меньше, чем (#([],[])) "2a3 4m" .

Результатом функции является 2e3 of the mapping of the numbers and operators.

Вот что такое lex ed for each of the test cases:

e

Оператор запятая в выражении JavaScript возвращает результат последнего выражения, поэтому N automatically returns a usable expression.

D sign is needed before the q изменить m to a и (#([],[])) (x:r)#(o,n)|x>'9'=r#h(o++[x],n)|[(a,t)]<-lex$x:r=t#h(o,read a:n) _#(o,n:_)=n h=e.e e(o:s,n:m:r)|o>'N'=e(s,g[o]n m:r) e(o:s,n:r)|o=='D'=e(s,n:n:r)|o=='N'=e(s,-n:r) e(o:s,n)|(p,m)<-e(s,n)=(o:p,m) e t=t g"a"=(+) g"m"=(*) g"q"=(((0^).abs).).(-) to * .

С использованием sys49152 as both the variable и оператор дублирования значительно упрощает 00 C0 A2 00 86 29 86 26 86 27 86 28 86 4B 86 4C 86 CC 20 E4 FF F0 FB C9 0D F0 10 C9 20 30 F3 A6 27 9D B7 C2 20 D2 FF E6 27 D0 E7 C6 CC A9 20 20 1C EA A9 0D 20 D2 FF 20 95 C0 20 09 C1 20 95 C0 A6 26 E4 27 F0 4E BD B7 C2 E6 26 C9 20 F0 E8 C9 2D D0 09 A6 4C A9 01 9D B7 C3 D0 32 C9 22 D0 09 A6 4C A9 02 9D B7 C3 D0 25 C9 2B D0 09 A6 4C A9 81 9D B7 C3 D0 18 C9 2A D0 09 A6 4C A9 82 9D B7 C3 D0 0B C9 3D D0 0D A6 4C A9 83 9D B7 C3 E6 28 E6 4C D0 A3 4C 8A C2 A6 29 F0 6F A4 28 F0 6B CA F0 4B C6 28 A6 4B E6 4B BD B7 C3 F0 F5 30 14 AA CA D0 0B 20 7B C2 20 E1 C1 20 4D C2 D0 D9 20 5C C2 D0 D4 29 0F AA CA D0 0B 20 6D C2 20 08 C2 20 4D C2 D0 C3 CA D0 0B 20 6D C2 20 16 C2 20 4D C2 D0 B5 20 6D C2 20 F4 C1 20 4D C2 D0 AA A4 4B B9 B7 C3 F0 02 10 AC C8 C4 4C F0 0F B9 B7 C3 F0 F6 30 F4 AA A9 00 99 B7 C3 F0 A6 60 A0 00 A6 26 E4 27 F0 15 BD B7 C2 C9 30 30 0E C9 3A 10 0A E6 26 99 37 C4 C8 C0 05 D0 E5 C0 00 F0 08 A9 00 99 37 C4 20 39 C2 60 A2 FF E8 BD 37 C4 D0 FA A0 06 88 CA 30 0A BD 37 C4 29 0F 99 37 C4 10 F2 A9 00 99 37 C4 88 10 F8 A9 00 8D 3D C4 8D 3E C4 A2 10 A0 7B 18 B9 BD C3 90 02 09 10 4A 99 BD C3 C8 10 F2 6E 3E C4 6E 3D C4 CA D0 01 60 A0 04 B9 38 C4 C9 08 30 05 E9 03 99 38 C4 88 10 F1 30 D2 A2 06 A9 00 9D 36 C4 CA D0 FA A2 10 A0 04 B9 38 C4 C9 05 30 05 69 02 99 38 C4 88 10 F1 A0 04 0E 3D C4 2E 3E C4 B9 38 C4 2A C9 10 29 0F 99 38 C4 88 10 F2 CA D0 D6 C0 05 F0 06 C8 B9 37 C4 F0 F6 09 30 9D 37 C4 E8 C8 C0 06 F0 05 B9 37 C4 90 F0 A9 00 9D 37 C4 60 A9 FF 45 FC 85 9F A9 FF 45 FB 85 9E E6 9E D0 02 E6 9F 60 A2 00 86 9F A5 FB C5 FD D0 07 A5 FC C5 FE D0 01 E8 86 9E 60 A5 FB 18 65 FD 85 9E A5 FC 65 FE 85 9F 60 A9 00 85 9E 85 9F A2 10 46 FC 66 FB 90 0D A5 FD 18 65 9E 85 9E A5 FE 65 9F 85 9F 06 FD 26 FE CA 10 E6 60 20 33 C1 A6 29 AD 3D C4 9D 3F C4 AD 3E C4 9D 3F C5 E6 29 60 A6 29 A5 9E 9D 3F C4 A5 9F 9D 3F C5 E6 29 60 A6 29 BD 3E C4 9D 3F C4 BD 3E C5 9D 3F C5 E6 29 60 C6 29 A6 29 BD 3F C4 85 FD BD 3F C5 85 FE C6 29 A6 29 BD 3F C4 85 FB BD 3F C5 85 FC 60 A6 29 BD 3E C5 10 13 20 7B C2 20 E1 C1 20 4D C2 A9 2D 20 D2 FF A6 29 BD 3E C5 8D 3E C4 BD 3E C4 8D 3D C4 20 8B C1 A9 37 A0 C4 4C 1E AB 's sub-expressions.

Тестовые случаи:

_ ||answer||

JavaScript, 321 311 байт

*

Попробуйте онлайн!

Пять символов такие же, как в вопросе, за исключением _="f=a=>(a.replace(/\\d+|./g,mq!~(b='+*=\"- '.indexOf(a))|b>2j3j4j5&&o+aw1/y?(y*=-1wcz:1/y?oywcz:hz,rql.map(z=>m(lki,1)[0],i)),hq1/s[1]?sk0,2,+eval(`y${a=='='?a+a:a}s[1]`)):cz,cqlki,0,a),s=[],l=[],e='splice'),s)z(a,i)ys[0]w)^r``:q=z=>os.unshift(k[e](j?b-";for(i of"jkoqwyz")with(_.split(i))_=join(pop());eval(_) is for multiplication.
Скрипт сжимается с помощью РегПак. Исходный скрипт хранится в переменной let f= (s,N=s.replace(/(-?\d+)-|-(-)/g,'- $1 ').match(/(- ?)*?\d+|R/g))=>+eval(`R=${N[0]>'9'?N[1]:N[0]},${s.match(/[+*=]/g).map((o,i)=>'R=R'+o+'='+N[i+1])}`) console.log(f('1+2*3')) // 9 console.log(f('1R+R+')) // 4 console.log(f('2R**R')) // 16 console.log(f('3R*+R')) // 18 console.log(f('3R+*R')) // 36 console.log(f('123R=')) // 1 console.log(f('1+2=3')) // 1 console.log(f('1R=2+')) // 3 console.log(f('1-2-+')) // -3 console.log(f('-1-2+')) // 3 console.log(f('*+R10 10')) //110 console.log(f('+*R10 10')) //200 console.log(f('-1+--2')); // 1 console.log(f('-1+-2')); // -3 after evaluation.

 

Rammf


Рег
04 Dec, 2008

Тем
56

Постов
175

Баллов
495
  • 26, Oct 2024
  • #3

6502 машинный код (C64), 697 байт

map

Онлайн демо

Использование R , then enter the anyfix expression and press return.

  • проверка ошибок практически отсутствует, поэтому ожидайте забавных результатов в случае недопустимых выражений.
  • символ умножения 0 , all others as suggested.
  • максимальная длина ввода — 256 символов, в очереди может быть не более 127 операторов.
  • Процедура ввода не делает обрабатывайте управляющие символы, поэтому не допускайте ошибок;)
  • целые числа имеют 16-битный знак, переполнение будет происходить автоматически.
  • количество байтов немного велико, потому что этот процессор даже не умеет умножать, а ОС/ПЗУ C64 не дает вам любой целочисленная арифметика или преобразования в/из десятичных строк.

Вот читаемый исходный код ассемблера в стиле ca65.

 

Prihod


Рег
10 Feb, 2010

Тем
52

Постов
221

Баллов
511
  • 26, Oct 2024
  • #4

Хаскелл, 251 байт

false

Попробуйте онлайн! Использует следующие символы: 1 for addition, true для умножения, eval for equality, + для дубликатов и map for negation. (I wanted to use 0+2*3 R=0,R=R+=2,R=R*=3 = 6 1+2*3 R=1,R=R+=2,R=R*=3 = 9 1R+R+ R=1,R=R+=R,R=R+=R = 4 2R**R R=2,R=R*=R,R=R*=R = 16 3R*+R R=3,R=R*=R,R=R+=R = 18 3R+*R R=3,R=R+=R,R=R*=R = 36 123R= R=123,R=R==R = 1 1+2=3 R=1,R=R+=2,R=R==3 = 1 1R=2+ R=1,R=R==R,R=R+=2 = 3 1-2-+ R=- 1,R=R+=- 2 = -3 -1-2+ R=1,R=R+=2 = 3 *+R10 10 R=10,R=R*=10,R=R+=10 = 110 +*R10 10 R=10,R=R+=10,R=R*=10 = 200 -1+--2 R=-1,R=R+=- -2 = 1 -1+-2 R=-1,R=R+=-2 = -3 за равенство, но столкнулся с проблемой, что eval parses eval в виде числа.) Пример использования: N yields s.match .

 

Isakovabdulakhmedovich


Рег
02 Dec, 2019

Тем
85

Постов
174

Баллов
609
  • 26, Oct 2024
  • #5

VB.NET (.NET 4.5) 615 576 байт

-39 байт благодаря Феликсу Пальмену за изменение eval to - -1

Требует -1- (included in byte count)

- 1

Точкой входа является функция 1- , which takes a string as input and returns a replace .

Символы:

  • Добавление - N
  • Умножение - R
  • Равенство - *
  • Отрицание - (s, N=s.replace(/(-?\d+)-|-(-)/g,'- $1 '). //change postfix negatives to prefix, //and change "--" to "- - " match(/(- ?)*?\d+|R/g) //grab numbers and duplicates )=>+eval(`R=${N[0] > '9' ? N[1] : N[0]}, //handle a delayed duplicate ${s.match(/[+*=]/g). //grab the operators map((o,i)=>'R=R'+o+'='+N[i+1]) //create a comma-separated list of assignments } `)
  • Дублирование - (s,N=s.replace(/(-?\d+)-|-(-)/g,'- $1 ').match(/(- ?)*?\d+|R/g))=>+eval(`R=${N[0]>'9'?N[1]:N[0]},${s.match(/[+*=]/g).map((o,i)=>'R=R'+o+'='+N[i+1])}`)

Обзор:

Функция e => e.replace( // given an expression e, for each value v matching /\d+|\S/g, v => { // a group of digits or any other non-whitespace char. for( // this loop processes as many operators as possible ( // insert v at the beginning of the relevant stack: 1 / v ? s : v > ',' ? u : b // either value, unary operator or binary operator )[U = 'unshift'](v); // (s[], u[] or b[] respectively) !!u[0] / s[0] ? // if there's at least 1 value and 1 unary operator: s[U]( // unshift into s[]: u.pop() > 'c' ? // for the duplicate operator: s[0] // a copy of the last value : // else, for the negative operator: -S() // the opposite of the last value ) : // end of unshift() !!b[0] / s[1] ? // if there's at least 2 values and 1 binary operator: s[U]( // unshift into s[]: +eval( // the result of the following expression: S(o = b.pop()) + // the last value, followed by the (o < '$' ? '==' : o) + // binary operator o with '#' replaced by '==' S() // followed by the penultimate value ) // end of eval() ) : 0; // end of unshift() ); // end of for() }, // end of replace() callback s = [], // initialize the value stack s[] u = [], // initialize the unary operator stack u[] b = [], // initialize the binary operator stack b[] S = _ => s.shift() // S = helper function to shift from s[] ) | s // return the final result takes the input and tokenizes it. It uses a let f = e=>e.replace(/\d+|\S/g,v=>{for((1/v?s:v>','?u:b)[U='unshift'](v);!!u[0]/s[0]?s[U](u.pop()>'c'?s[0]:-S()):!!b[0]/s[1]?s[U](+eval(S(o=b.pop())+(o<'$'?'==':o)+S())):0;);},s=[],u=[],b=[],S=_=>s.shift())|s ;[ '10+5', '10+d', '*+d10 10', '1+2*3', '1d+d+', '2d**d', '3d*+d', '3d+*d', '123d#', '1+2#3', '1d#2+', '1-2-+', '-1-2+' ] .forEach(e => console.log(e, '-->', f(e))) подсчитать промежуточный итог для многозначных целых чисел, что - signifying we are not currently reading an integer.

Подпрограмма d takes the stack of integers and queue of operators, and evaluates the anyfix notation. It calls itself recursively until there are no actions left.

Я объявляю глобальные параметры сразу, чтобы сэкономить байты как при объявлении, так и при передаче параметров.

Возвращаемое значение из # is set by assigning a value to the matching variable * .

ВБ + is equivalent to e=>e.replace(/\d+|\S/g,v=>{for((1/v?s:v>','?u:b)[U='unshift'](v);!!u[0]/s[0]?s[U](u.pop()>'c'?s[0]:-S()):!!b[0]/s[1]?s[U](+eval(S(o=b.pop())+(o<'$'?'==':o)+S())):0;);},s=[],u=[],b=[],S=_=>s.shift())|s , так что операция должна инвертировать результат, чтобы получить правильное значение.

Попробуйте онлайн!

 

MAXS1MKA87


Рег
22 May, 2012

Тем
70

Постов
190

Баллов
580
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно