Математика в Манхэттене

12

Я определяю следующие операторы:

Манхэттен Добавление a + M b для однозначных чисел является результатом объединения b на a. Итак, a + M b = 10a + b. Следовательно, общий оператор + M определяется следующим образом:

a + M b = 10a + b

Манхэттенское вычитание a - M b, для однозначных чисел, является результатом удаления последнего b из a. Следовательно, оператор - M определяется так, как в псевдокоде:

a - M b = удалить последний б

Манхэттенское Умножение a × M b является результатом замены всех экземпляров b в a на b экземпляров b. Ergo, × M определяется в псевдокоде как:

a × M b = a -> s / b / <b копий b> / g

Манхэттенский отдел a ÷ M b определяется в терминах × M :

1 ÷ M b = первый символ b
a ÷ M b = a × M (1 ÷ M b)

Имея все это в виду, создайте интерпретатор, который будет оценивать инфиксные выражения, которые используют следующие операторы (то есть a + b, не a b +или + a b)

+    Addition
-    Subtraction
/    Division
*    Multiplication
*M   Manhattan Multiplication
/M   Manhattan Division
+M   Manhattan Addition
-M   Manhattan Subtraction

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

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

> 5 +M 10 + 3
63      // 5*10 + 10 + 3 => 60 + 3
> 10 *M 2
10      // no 2s in 10
> 10 *M 1
10      // one 1 in 10 replaced once
> 23 *M 3
2333    // 23 has one 3, which is replaced with three 3s
> 23 *M 2
223     // 23 has one 2, which is replaced with two 2s
> 232 *M 2
22322   // 232 has two 2s, which are replaced with two 2s
> 232 *M 23
23...(23 times)...232   // ...
> 123 *M 2 * 3
3669    // 1223 * 3 => 3669
> 5 + 3 +M 2
37      // 5 + (3 +M 2) => 5 + 32 => 37
> 150 /M 3
150     // 150 ÷M 3 => 150 ×M 3 => 150
> 150 /M 53
1555550 // 150 ÷M 53 => 150 ×M 5 => 1555550
> 50 -M 0
5
> 500 -M 0
50
> 5234 -M 5
234
> 12 +M 633 *M 3
6333453 // = 12 +M 6333333 = 120 + 6333333 = 6333453

Это , поэтому выигрывает самая короткая программа в байтах.

Leaderboards

Вот фрагмент стека, который генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам.

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

# Language Name, N bytes

где Nразмер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Если вы хотите включить в заголовок несколько чисел (например, потому что ваш счет равен сумме двух файлов или вы хотите перечислить штрафы за флаг интерпретатора отдельно), убедитесь, что фактический результат является последним числом в заголовке:

# Perl, 43 + 2 (-p flag) = 45 bytes

Вы также можете сделать название языка ссылкой, которая затем будет отображаться в фрагменте списка лидеров:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

Конор О'Брайен
источник
13
Почему вы используете символы Unicode, ×а ÷не ASCII *и /?
ASCIIThenANSI
1
Почему 232 ×M 23равняется 23232? Разве это не должно равняться 23 копиям с 23последующим 2?
Сеншин
1
@ASCIIThenANSI Я понимаю, почему ты это спросил. Выбор произвольный. Если с моим выбором не возникнет какой-либо насущной проблемы, я не думаю, что я ее поменяю.
Конор О'Брайен
4
Это делает его более трудным для произвольно языков без хорошей поддержки Unicode для участия, что не очень интересно, если проблема не о Unicode.
Линн
2
Этот вопрос не получил достаточного внимания, потому что не очень хорошо определен. Вы определяете сложение для однозначных чисел, тогда ваш первый пример имеет двухзначные числа. Я сдаюсь ...
edc65

Ответы:

5

Dyalog APL , 104 81 79 93 75 байтов

Изменить: Теперь обрабатывает 4342343 -M 3443423правильно.

M←{⍎(5|⌊⍺⍺2)⊃'⍺×M⍣(⍺≠1)⍎⊃b'(b⎕R(⍵⍴'&')⊢a)'10⊥⍺⍵'(('(.*)',b←⍕⍵)⎕R'\1'⊢a←⍕⍺)}

Фон

Это расширяет APL, чтобы включить оператора Манхэттена. Оператор в терминологии APL является модификатором функций (например ÷). Примером оператора является то, что модифицирует функции, чтобы поменять их аргументы так 3 = 2 ÷⍨ 6. Также Mизменяет основные арифметические функции, чтобы быть их родственниками на Манхэттене. Обратите внимание, что поскольку полученный язык является расширением APL, строгий приоритет справа налево сохраняется.

объяснение

Общая структура - это M←{⍎(5|⌊⍺⍺2)⊃... }которая применяет функцию ( +или -или ×или ÷) к 2 и использует результат для выбора строки для оценки. Строки:

3 для -M: (('(.*)',b←⍕⍵)⎕R'\1'⊢a←⍕⍺)
 регулярное выражение удаляет последнее вхождение b (строковый респ из правого аргумента) в a (строковый респ из левого аргумента)

2 для + M: '10⊥⍺⍵'
 оцените аргументы как цифры от 10 до 10

1 для × M: (b⎕R(⍵⍴'&')⊢a)
 заменить вхождения b на амперсанды b (т. Е. Регулярное выражение для

0 для ÷ M: '⍺×M⍣(⍺≠1)⍎⊃b'
⍎⊃b первая цифра b
⍺×M⍣(⍺≠1) применяется ⍺ × M, если ⍺ ≠ 1

Из вышеперечисленных четырех строк выберите номер:

(5|⌊⍺⍺2)mod-5 этажа функции применяется к 2, а именно:
 3 = 5 | ⌊-2
 2 = 5 | ⌊+2
 1 = 5 | ⌊×2потому что × 2 ⇔ sgn (2) ⇔ 1
 0 = 5 | ⌊÷2потому что ÷ 2 ⇔ 1 ÷ 2 ⇔ 0,5

Большое спасибо моему дорогому другу Нгну за потрясающую стружку.

Адам
источник
1
Это отлично. Это соответствует тому, что я хотел.
Конор О'Брайен
Отлично, тогда я отредактирую пост.
Адам
@ CᴏɴᴏʀO'Bʀɪᴇɴ Я мог потерять бонус, но сейчас он самый короткий.
Адам
Ой, забыл об этом.
Конор О'Брайен
@ CᴏɴᴏʀO'Bʀɪᴇɴ Забыли? Я только что отредактировал сегодня, сделав его короче принятого.
Адам
12

Perl, 100 99 98 байт

Код 97 байтов + командная строка 1 байт

s/ |.*\K(\d)(\d*)-M\1|\+M/\2/g+s/(\d+)\*M(.)/$1=~s@$2@$&x$&@erg/e+s#/(M.)\d+#*\1#&&redo,$\=eval}{

Пример использования:

echo "123 *M 2 * 3 + 150 /M 53" | perl -p entry.pl
Jarmex
источник
Если это делает ваш код короче, вы должны использовать только *Mдля xMи /Mдля <div>M.
Конор О'Брайен
Поздравляю с наградой!
Конор О'Брайен
7

Python, 644 байта

import operator as o,re
x,q,t,r,w='*/+-M';mm,md,ma,ms='*M /M +M -M'.split()
n=lambda x:x
a=lambda a,b:str(10*int(a)+int(b))
v=lambda a,b:a[::-1].replace(b,'',1)[::-1]
m=lambda a,b:a.replace(b,b*int(b))
d=lambda a,b:m(a,b[0])if a>0 else b[0]
def p(s):s=s.group();ss=s.split();l=s.split(ss[1]);h={mm:m,md:d,ma:a,ms:v,x:o.mul,q:o.div,t:o.add,r:o.sub}.get(ss[1],n);return str(h(*map(int if h in[o.mul,o.div,o.add,o.sub]else n,map(u,map(str.strip,l)))))
def u(s):z=r'\d+ (?:\{0}{2}|\{1}{2}) \d+';return re.sub(z.format(t,r,''),p,re.sub(z.format(t,r,w),p,re.sub(z.format(x,q,''),p,re.sub(z.format(x,q,w),p,re.sub(r'\((.*)\)',u,s)))))
print u(input())

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

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

Mego
источник
Я не вижу cили f.
РК.