Matematyka na Manhattanie

12

Definiuję następujące operatory:

Dodatek Manhattanu a + Mb , dla liczb jednocyfrowych, jest wynikiem połączenia b na a. Zatem a + Mb = 10a + b. Dlatego operator ogólny + M jest zdefiniowany w następujący sposób:

a + Mb = 10a + b

Odejmowanie Manhattan a - M b, dla liczb jednocyfrowych, jest wynikiem usunięcia ostatniego b z a. Dlatego operator - M jest zdefiniowany w ten sposób w pseudokodzie:

a - M b = usuń ostatni b

Mnożenie Manhattanu a × M b jest wynikiem zastąpienia wszystkich wystąpień b in a przez b wystąpienia b. Ergo, × M jest zdefiniowane w pseudokodzie jako:

a × M b = a -> s / b / <b kopie b> / g

Rejon Manhattanu a ÷ M b definiuje się w kategoriach × M :

1 ÷ M b = pierwszy znak b
a ÷ M b = a × M (1 ÷ M b)

Mając to wszystko na uwadze, utwórz interpreter, który będzie oceniał wyrażenia niepoprawne korzystające z następujących operatorów (tj. a + bNie a b +lub + a b)

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

Każdy operator na Manhattanie ma wyższy priorytet niż ich normalny odpowiednik.

Przypadki testowe:

> 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

To jest , więc wygrywa najkrótszy program w bajtach.

Liderów

Oto fragment kodu, który pozwala wygenerować zarówno zwykłą tabelę wyników, jak i przegląd zwycięzców według języka.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

# Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

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

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie tabeli wyników:

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

Conor O'Brien
źródło
13
Dlaczego używasz symboli Unicode ×i ÷zamiast ASCII *i /?
ASCIIThenANSI
1
Dlaczego jest 232 ×M 23równy 23232? Czy nie powinno to oznaczać 23 kopii, 23po których następuje 2?
senshin
1
@ASCIIThenANSI Rozumiem, dlaczego o to prosiłeś. Wybór jest dowolny. Chyba że z moim wyborem jest jakiś naglący problem, nie sądzę, żebym go zmienił.
Conor O'Brien
4
Utrudnia to arbitralnie udział języków bez dobrej obsługi Unicode, co nie jest zbyt zabawne, jeśli wyzwanie nie dotyczy Unicode.
Lynn
2
Na to pytanie nie zwrócono wystarczającej uwagi, ponieważ nie zostało dobrze określone. Definiujesz dodawanie liczb sngle, a następnie twój pierwszy przykład ma 2 cyfry.
Poddaję

Odpowiedzi:

5

Dyalog APL , 104 81 79 93 75 bajtów

Edycja: teraz obsługuje 4342343 -M 3443423poprawnie.

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

tło

To rozszerza APL o operatora Manhattan. Operator w terminologii APL jest modyfikatorem funkcji (np ÷.). Przykładem operatora jest modyfikowanie funkcji w celu zamiany ich argumentów 3 = 2 ÷⍨ 6. Podobnie Mmodyfikuje podstawowe funkcje arytmetyczne, aby były ich krewnymi na Manhattanie. Zauważ, że ponieważ powstały język jest rozszerzeniem APL, pozostaje ścisły priorytet APL od prawej do lewej.

Wyjaśnienie

Nadrzędną strukturą jest M←{⍎(5|⌊⍺⍺2)⊃…, }która stosuje funkcję ( +lub -lub ×lub ÷) do 2 i wykorzystuje wynik do wyboru, który ciąg ma zostać oceniony. Ciągi to:

3 dla -M: (('(.*)',b←⍕⍵)⎕R'\1'⊢a←⍕⍺)
 regex usunąć ostatni występowania b (.. Smyczkowy rep z prawej Arg) w a (string rep od lewej arg.).

2 dla + M: '10⊥⍺⍵'
 oceń argumenty jako 10 cyfr bazowych

1 do x M: (b⎕R(⍵⍴'&')⊢a)
 zastąpienie wystąpienia b o b ampersandów (to wyrażenie regularne dla

0 dla ÷ M: stosuje się '⍺×M⍣(⍺≠1)⍎⊃b'
⍎⊃bpierwszą cyfrę b
⍺×M⍣(⍺≠1) ⍺ × M, jeśli ⍺ ≠ 1

z powyższych czterech ciągów wybierz numer:

(5|⌊⍺⍺2)mod-5 podłogi funkcji zastosowanej do 2, a mianowicie:
 3 = 5 | ⌊-2
 2 = 5 | ⌊+2
 1 = 5 | ⌊×2ponieważ × 2 ⇔ sgn (2) ⇔ 1
 0 = 5 | ⌊÷2ponieważ ÷ 2 ⇔ 1 ÷ 2 ⇔ 0,5

Ogromne podziękowania dla mojego drogiego przyjaciela ngn za niesamowite wióry.

Adám
źródło
1
Jest okej. Pasuje do tego, czego chciałem.
Conor O'Brien,
Świetnie, wtedy wyedytuję post.
Adám,
@ CᴏɴᴏʀO'Bʀɪᴇɴ Mogłem stracić premię, ale z pewnością jest ona teraz najkrótsza.
Adám
Ups, zapomniałem o tym.
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Zapomniałeś? Właśnie edytowałem dzisiaj, dzięki czemu jest krótszy niż zaakceptowany.
Adám
12

Perl, 100 99 98 bajtów

Kod 97 bajtów + 1 bajt wiersz poleceń

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

Przykład użycia:

echo "123 *M 2 * 3 + 150 /M 53" | perl -p entry.pl
Jarmex
źródło
Jeśli sprawia, że ​​Twój kod jest krótszy, musisz używać tylko *Mdla xMi /Mdla <div>M.
Conor O'Brien
Gratulujemy nagrody!
Conor O'Brien
7

Python, 644 bajty

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

Akceptuje dane wejściowe STDIN (zawinięte w cudzysłów). Używa wyrażeń regularnych do dopasowywania i analizowania operacji. Cała praca jest wykonywana na ciągach, a rzutowanie do i od ints jest używane tylko podczas wykonywania normalnych operacji matematycznych.

Jestem prawie pewien, że można by dalej grać w golfa, więc będę pracował nad tym przez kilka następnych dni.

Mego
źródło
Nie widzę cani f.
RK.