Математика на Манхеттені


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 видалити останній b

Множення Манхеттена a × M b є результатом заміни всіх екземплярів b в a на екземплярами 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

Це , тому виграє найкоротша програма в байтах.

Табло лідерів

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

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

# 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а за ними - a 2?
сеншин

1
@ASCIIThenANSI Я бачу, чому ви це запитували. Вибір умовний. Якщо не буде певного питання з моїм вибором, я не думаю, що я його зміню.
Conor O'Brien

4
Це робить довільно важче для мов без гарної підтримки Unicode брати участь, що не дуже цікаво, якщо виклик не стосується Unicode.
Лінн

2
Це питання не приділяло належної уваги, оскільки воно не було чітко визначено. Ви визначаєте додавання для чисельних цифр, то ваш перший приклад має 2 цифри. Я
здаюсь

Відповіді:


5

Діалог 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, то зберігається чіткий пріоритет APL справа наліво.

Пояснення

Загальна структура - це M←{⍎(5|⌊⍺⍺2)⊃…, }яка застосовує функцію ( +або -або ×або ÷) до 2 і використовує результат, щоб вибрати, який рядок оцінювати. Струни:

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

2 для + M: '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

Багато подяк моєму дорогому другові ngn за дивовижні стружки.


1
Це добре. Це відповідає тому, що я хотів.
Conor O'Brien

Чудово, я редагуватиму пост тоді.
Adám

@ CᴏɴᴏʀO'Bʀɪᴇɴ Я, можливо, програв бонус, але зараз це впевнено.
Adám

ой, забув про це.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Забув? Я щойно відредагував, зробивши його коротшим, ніж прийнятий.
Adám

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

Якщо це робить ваш код коротшим, вам доведеться використовувати лише *Mдля xMі /Mдля <div>M.
Conor O'Brien

З повагою!
Conor O'Brien

7

Пітон, 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 (загорнуте в лапки). Використовує регулярний вираз для відповідності та розбору операцій. Вся робота виконується на рядках, а лиття в і з ints використовується лише під час виконання звичайних математичних операцій.

Я майже впевнений, що це може бути додатково гольф, тому я буду над цим працювати протягом наступних кількох днів.


Я не бачу cабо f.
РК.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.