Matemática em manhattan

12

Eu defino os seguintes operadores:

A adição de Manhattan a + M b, para números de um dígito, é o resultado da concatenação de b em a. Então, a + M b = 10a + b. Portanto, o operador geral + M é definido da seguinte maneira:

a + M b = 10a + b

Subtração de Manhattan a - M b, para números de um dígito, é o resultado da remoção do último b de a. Portanto, o operador - M é definido da seguinte maneira no pseudocódigo:

a - M b = a remove o último b

Multiplicação de Manhattan a × M b é o resultado da substituição de todas as instâncias de b em a por b instâncias de b. Ergo, × M é definido no pseudocódigo como:

a × M b = a -> s / b / <b cópias de b> / g

A Divisão de Manhattan a ÷ M b é definida em termos de × M :

1 ÷ M b = o primeiro caractere de b
a ÷ M b = a × M (1 ÷ M b)

Com tudo isso em mente, crie um intérprete que avaliará expressões infix que usam os seguintes operadores (ou seja a + b, não a b +ou + a b)

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

Cada operador de Manhattan tem uma precedência de ordem mais alta que sua contraparte normal.

Casos de teste:

> 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 é um , portanto o programa mais curto em bytes vence.

Classificação

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

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

Você também pode transformar o nome do idioma em um link que será exibido no snippet do placar de líderes:

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

Conor O'Brien
fonte
13
Por que você está usando os símbolos Unicode ×e ÷não ASCII *e /?
ASCIIThenANSI
1
Por que 232 ×M 23igual 23232? Não deveria ser igual a 23 cópias 23seguidas de a 2?
Senshin
1
@ASCIIThenANSI Entendo por que você perguntou isso. A escolha é arbitrária. A menos que haja algum problema urgente com minha escolha, acho que não vou mudar.
Conor O'Brien
4
Isso torna mais difícil para arbitrariamente línguas sem um bom suporte a Unicode para participar, o que não é muito divertido, se o desafio não é sobre Unicode.
Lynn
2
Esta pergunta não recebeu atenção suficiente porque não está bem especificada. Você define adição para números de dígitos únicos e, em seguida, seu primeiro exemplo tem números de 2 dígitos. Eu desisto ...
edc65 8/08

Respostas:

5

Dyalog APL , 104 81 79 93 75 bytes

Editar: Agora lida com 4342343 -M 3443423corretamente.

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

fundo

Isso estende o APL para incluir o operador Manhattan. Um operador na terminologia da APL é um modificador de funções (por exemplo ÷). Um exemplo de operador é que modifica funções para trocar seus argumentos 3 = 2 ÷⍨ 6. Também Mmodifica as funções aritméticas básicas para serem seus parentes em Manhattan. Observe que, como o idioma resultante é uma extensão do APL, a estrita precedência da direita para a esquerda permanece.

Explicação

A estrutura abrangente é M←{⍎(5|⌊⍺⍺2)⊃}que aplica a função ( +ou -ou ×ou ÷) a 2 e usa o resultado para escolher qual sequência de caracteres avaliar. As strings são:

3 para -M: (('(.*)',b←⍕⍵)⎕R'\1'⊢a←⍕⍺)
 regex remove a última ocorrência de b (sequência de caracteres do argumento à direita) em a (representação de sequência do argumento à esquerda)

2 para + M: '10⊥⍺⍵'
 avalie os argumentos como dígitos da base 10

1 para × M: (b⎕R(⍵⍴'&')⊢a)
 substitua as ocorrências de b por b e comercial (ou seja, regex para o

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

dentre as quatro seqüências acima, escolha o número:

(5|⌊⍺⍺2)mod-5 do piso da função aplicada a 2, a saber:
 3 = 5 | ⌊-2
 2 = 5 | ⌊+2
 1 = 5 | ⌊×2porque × 2 gn sgn (2) ⇔ 1
 0 = 5 | ⌊÷2porque ÷ 2 ⇔ 1 ÷ 2 ⇔ 0,5

Muito obrigado ao meu querido amigo ngn por aparas incríveis.

Adão
fonte
1
Isto é bom. Isso se encaixa no que eu desejava.
Conor O'Brien
Ótimo, eu vou editar o post então.
Adám
@ CᴏɴᴏʀO'Bʀɪᴇɴ Eu posso ter perdido o bônus, mas com certeza é o mais curto agora.
Adám
Opa, esqueci esse aqui.
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Esqueceu? Acabei de editar hoje, tornando-o mais curto que o aceito.
Adám
12

Perl, 100 99 98 bytes

Código de 97 bytes + linha 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}{

Exemplo de uso:

echo "123 *M 2 * 3 + 150 /M 53" | perl -p entry.pl
Jarmex
fonte
Se o código for mais curto, você precisará usar apenas *Mpara xMe /Mpara <div>M.
Conor O'Brien
Parabéns pela 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())

Aceita entrada em STDIN (entre aspas). Usa regex para combinar e analisar operações. Todo o trabalho é feito em seqüências de caracteres, e a conversão de e para ints é usada apenas ao realizar operações matemáticas normais.

Tenho certeza de que isso pode ser ainda mais aprimorado, por isso vou trabalhar nisso nos próximos dias.

Mego
fonte
Eu não vejo um cou f.
RK.