Matemáticas en Manhattan

12

Defino los siguientes operadores:

La adición de Manhattan a + M b, para números de un solo dígito, es el resultado de concatenar b sobre a. Entonces, a + M b = 10a + b. Por lo tanto, el operador general + M se define así:

a + M b = 10a + b

Resta de Manhattan a - M b, para números de un solo dígito, es el resultado de eliminar la última b de a. Por lo tanto, el operador - M se define así en pseudocódigo:

a - M b = a eliminar el último b

Manhattan Multiplication a × M b es el resultado de reemplazar todas las instancias de b en a por b instancias de b. Ergo, × M se define en pseudocódigo como:

a × M b = a -> s / b / <b copias de b> / g

Manhattan Division a ÷ M b se define en términos de × M :

1 ÷ M b = el primer carácter de b
a ÷ M b = a × M (1 ÷ M b)

Con todo esto en mente, cree un intérprete que evaluará las expresiones infija que utilizan los siguientes operadores (es decir a + b, no a b +o + a b)

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

Cada operador de Manhattan tiene una precedencia de orden más alta que su contraparte normal.

Casos de prueba:

> 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

Este es un , por lo que gana el programa más corto en bytes.

Tablas de clasificación

Aquí hay un fragmento de pila para generar una tabla de clasificación regular y una descripción general de los ganadores por idioma.

Para asegurarse de que su respuesta se muestre, comience con un título, usando la siguiente plantilla de Markdown:

# Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

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

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

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

También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento de la tabla de clasificación:

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

Conor O'Brien
fuente
13
¿Por qué estás usando los símbolos Unicode ×y en ÷lugar de ASCII *y /?
ASCIIThenANSI
1
¿Por qué es 232 ×M 23igual 23232? ¿No debería ser igual a 23 copias 23seguidas de a 2?
senshin
1
@ ASCIIThenANSI Puedo ver por qué preguntaste eso. La elección es arbitraria. A menos que haya algún problema urgente con mi elección, no creo que lo cambie.
Conor O'Brien
44
Hace arbitrariamente más difícil la participación de idiomas sin un buen soporte de Unicode, lo que no es muy divertido, si el desafío no se trata de Unicode.
Lynn
2
Esta pregunta no ha recibido suficiente atención porque no está bien especificada. Usted define la suma de números de dígitos simples, luego su primer ejemplo tiene números de 2 dígitos. Me
rindo

Respuestas:

5

Dyalog APL , 104 81 79 93 75 bytes

Editar: ahora maneja 4342343 -M 3443423correctamente.

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

Antecedentes

Esto extiende APL para incluir al operador de Manhattan. Un operador en terminología APL es un modificador de funciones (por ejemplo ÷). Un ejemplo de un operador es el que modifica funciones para intercambiar sus argumentos 3 = 2 ÷⍨ 6. Así también, Mmodifica las funciones aritméticas básicas para ser sus parientes de Manhattan. Tenga en cuenta que, dado que el lenguaje resultante es una extensión de APL, la estricta precedencia de derecha a izquierda de APL permanece.

Explicación

La estructura general es M←{⍎(5|⌊⍺⍺2)⊃... }que se aplica la función ( +o -o ×o ÷) a 2 y utiliza el resultado de elegir qué cadena va a evaluar. Las cadenas son:

3 para -M: (('(.*)',b←⍕⍵)⎕R'\1'⊢a←⍕⍺)
 regex elimina la última aparición de b (rep. De cadena del argumento derecho) en a (rep. De cadena del argumento izquierdo).

2 para + M: '10⊥⍺⍵'
 evalúa los argumentos como dígitos de base 10

1 para × M: (b⎕R(⍵⍴'&')⊢a)
 reemplace las ocurrencias de b con ampersands b (es decir, regex para el

0 para ÷ M: '⍺×M⍣(⍺≠1)⍎⊃b'
⍎⊃b primer dígito de b se
⍺×M⍣(⍺≠1) aplica ⍺ × M si ⍺ ≠ 1

de las cuatro cadenas anteriores, elija el número:

(5|⌊⍺⍺2)mod-5 del piso de la función aplicada a 2, a saber:
 3 = 5 | ⌊-2
 2 = 5 | ⌊+2
 1 = 5 | ⌊×2porque × 2 ⇔ sgn (2) ⇔ 1
 0 = 5 | ⌊÷2porque ÷ 2 ⇔ 1 ÷ 2 ⇔ 0.5

Muchas gracias a mi querido amigo ngn por sus increíbles virutas.

Adán
fuente
1
Esto esta bien. Se ajusta a lo que había deseado.
Conor O'Brien
Genial, editaré la publicación entonces.
Adám
@ CᴏɴᴏʀO'Bʀɪᴇɴ Podría haber perdido el bono, pero ahora es el más corto.
Adám
Uy, se olvidó de este.
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ ¿Olvidó? Acabo de editar hoy, haciéndolo más corto que el aceptado.
Adám
12

Perl, 100 99 98 bytes

Código de 97 bytes + línea de comando de 1 byte

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

Ejemplo de uso:

echo "123 *M 2 * 3 + 150 /M 53" | perl -p entry.pl
Jarmex
fuente
Si acorta su código, solo tiene que usarlo *Mpara xMy /Mpara <div>M.
Conor O'Brien
¡Felicidades por la recompensa!
Conor O'Brien
7

Python, 644 bytes

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

Acepta entradas en STDIN (entre comillas). Utiliza expresiones regulares para comparar y analizar operaciones. Todo el trabajo se realiza en cadenas, y la conversión de entradas y salidas solo se usa cuando se realizan operaciones matemáticas normales.

Estoy bastante seguro de que esto podría jugar más, así que estaré trabajando en eso en los próximos días.

Mego
fuente
No veo una co f.
RK.