Implemente una calculadora de script de operación entera simple.
Concepto
El acumulador comienza en 0 y tiene operaciones realizadas en él. Al final de la salida del programa, el valor del acumulador.
Operaciones:
+
agrega1
al acumulador-
resta1
del acumulador*
multiplica el acumulador por2
/
divide el acumulador por2
Script de muestra
La entrada ++**--/
debe dar la salida 3
.
Implementación de ejemplo
def calc(s)
i = 0
s.chars.each do |o|
case o
when '+'
i += 1
when '-'
i -= 1
when '*'
i *= 2
when '/'
i /= 2
end
end
return i
end
Reglas
- Este es el código de golf , por lo que la respuesta más baja en bytes gana, pero no está seleccionada.
- Se recomiendan implementaciones creativas.
- Las lagunas estándar están prohibidas.
- Obtiene el programa a través de stdin o argumentos, y puede generar la respuesta a través del valor de retorno o stdout.
- Que te diviertas.
- La división se trunca porque es una división entera.
- El programa
-/
vuelve-1
.
Casos de prueba
*///*-*+-+
-1
/*+/*+++/*///*/+-+//*+-+-/----*-*-+++*+**+/*--///+*-/+//*//-+++--++/-**--/+--/*-/+*//*+-*-*/*+*+/+*-
-17
+++-+--/-*/---++/-+*-//+/++-*--+*+/*/*/++--++-+//++--*/***-*+++--+-*//-*/+*/+-*++**+--*/*//-*--**-/-*+**-/*-**/*+*-*/--+/+/+//-+*/---///+**////-*//+-+-/+--/**///*+//+++/+*++**++//**+**+-*/+/*/*++-/+**+--+*++++/-*-/*+--/++*/-++/-**++++/-/+/--*/-/+---**//*///-//*+-*----+//--/-/+*/-+++-+*-*+*+-/-//*-//+/*-+//+/+/*-/-/+//+**/-****/-**-//+/+-+/*-+*++*/-/++*/-//*--+*--/-+-+/+/**/-***+/-/++-++*+*-+*+*-+-//+/-++*+/*//*-+/+*/-+/-/*/-/-+*+**/*//*+/+---+*+++*+/+-**/-+-/+*---/-*+/-++*//*/-+-*+--**/-////*/--/*--//-**/*++*+/*+/-+/--**/*-+*+/+-*+*+--*///+-++/+//+*/-+/**--//*/+++/*+*////+-*-//--*+/*/-+**/*//+*+-//+--+*-+/-**-*/+//*+---*+//*/+**/*--/--+/*-*+*++--*+//+*+-++--+-*-*-+--**+/+*-/+*+-/---+-*+-+-/++/+*///*/*-+-*//-+-++/++/*/-++/**--+-////-//+/*//+**/*+-+/+/+///*+*///*-/+/*/-//-*-**//-/-+--+/-*--+-++**++//*--/*++--*-/-///-+/+//--+*//-**-/*-*/+*/-*-*//--++*//-*/++//+/-++-+-*/*-+++**-/-*++++**+-+++-+-***-+//+-/**-+/*+****-*+++*/-*-/***/-/*+/*****++*+/-/-**-+-*-*-++**/*+-/*-+*++-/+/-++*-/*-****-*
18773342
code-golf
math
number
arithmetic
dkudriavtsev
fuente
fuente
/
puede producir no enteros.-/
volver?Respuestas:
Python 2, 48 bytes
Ciervas
+2
,-2
,*2
, o/2
. Al hacer+2
y en-2
lugar de+1
y-1
, estamos trabajando en unidades duplicadas, por lo que el resultado final debe reducirse a la mitad. Excepto, la división de piso/
ahora necesita redondearse a un múltiplo de 2, lo que se hace con&-2
.fuente
0q{2\~-2&}/2/
(2\~
evalúa el operador con el segundo operando2
,-2&
es el AND bit a bit,2/
es la división final por dos.q{...}/
Es un foreach sobre la entrada y0
es solo el inicial valor.)Haskell, 51 bytes
Ejemplo de uso:
foldl(#)0 $ "++**--/"
->3
.fuente
Jalea ,
1817 bytesPruébalo en línea!
Cómo funciona
Las primeras seis líneas definen enlaces auxiliares con índices que van del 1 al 6 ; aumentan, no hacen nada, disminuyen, no hacen nada, se reducen a la mitad (pisos) y se duplican.
El enlace principal
O0;ṛĿ/
- convierte los caracteres de entrada a sus puntos de código (O
), antepone un 0 (valor inicial) a la matriz de puntos de código0;
, luego reduce la matriz generada de la siguiente manera.El valor inicial es el primer elemento de la matriz, es decir, el 0 antepuesto . Se
ṛĿ
llama al enlace rápido para cada elemento siguiente en la matriz, con el último valor de retorno como argumento izquierdo y el elemento actual como derecho. Inspecciona su argumento correcto (ṛ
) y evalúa el enlace con ese índice de forma monádica (Ŀ
), aplicando así la operación deseada.fuente
Python 2, 54 bytes
La entrada se toma como un literal de cadena.
~ord(c)%5%3
asigna los operadores a los correspondientes operandos derechos.Anteriormente, utilicé
hash(c)%55%3
lo que no produjo resultados consistentes entre diferentes versiones de Python. Esto me animó a explorar otras fórmulas.fuente
hash
es específica de la versión de Python: ideone usa 2.7.10 que da[1, 1, 2, 2]
como las cuatro asignaciones, mientras que localmente en 2.7.12 obtengo[2, 0, 1, 0]
SILOS ,
133211 bytesToma los códigos ASCII de los operadores.
Pruébelo en línea con casos de prueba:
-/
++**--/
*///*-*+-+
fuente
-/
debería devolver -1 , no 0 .Máquina de Turing - 23 estados (684 bytes)
Pruébalo aquí - enlace permanente
La entrada no debe contener ningún '*' ya que es un carácter especial en el código de máquina de Turing. Use 'x' en su lugar. Emite la respuesta en binario.
Código no ofuscado
Explicación de los estados:
Inicialización:
estos estados se visitan una vez al comienzo de cada ejecución, comenzando con init2
Instrucciones de lectura:
estos estados se visitarán varias veces durante todo el programa
readop: se mueve completamente hacia la derecha hasta que lee un operador o el '.'. Si golpea a un operador, cambie al estado correspondiente (+, -, x, /). Si toca un '.', Cambie al estado 'fin'.
return: Devuelve la cabeza al espacio vacío entre el total acumulado y los operadores. Luego cambia a 'readop'.
Operaciones:
estas operaciones hacen el trabajo sucio real
+: Mueve hacia la izquierda hasta que la cabeza lea cualquier carácter que no sea un espacio en blanco. Si este personaje es un '-', muévase a la izquierda y cambie a 'dec'. De lo contrario, cambie a 'inc'.
-: Similar a '+', excepto cambiar a 'inc' si hay un '-' y 'dec' de lo contrario.
inc: si el dígito debajo de la cabecera es un 0 (o un espacio en blanco), cámbielo a 1 y cambie a 'cero'. Si el dígito es un 1, cámbielo a 0, luego repita en el siguiente dígito.
dec: Similar a inc, excepto que 1 va a 0, 0 va a 1, y si la cabeza lee un espacio en blanco, cambie a 'neg'.
x, x0, x1: Bitshift el número uno a la izquierda. Cambiar a 'volver'.
/, //, div, div0, div1: muévete completamente a la derecha del número, luego desplaza uno a la derecha. Si hay un '-', cambie a 'inc'. Esto simula redondear números negativos. De lo contrario, cambie a 'cero'
neg: coloque un '-' después del número y luego cambie a 'readop'
cero, cero1, cero2: elimine los ceros a la izquierda y cambie a 'readop'
Limpieza: hace que la salida sea presentable
fuente
Perl 6 ,
5352 bytesExplicación:
Uso:
fuente
C,
636257 bytesCaja de varitas
fuente
05AB1E , 20 bytes
¡Gracias a Enigma por arreglar el
-/
error!Para 16 bytes si no fuera número entero división:
Î"+-*/""><·;"‡.V
.Explicación:
Utiliza la codificación CP-1252 . Pruébalo en línea!
fuente
-/
debería devolver -1 , no 0 .Î…+-*"><·"‡'/"2÷":.V
el mismo recuento de bytes.JavaScript ES6,
8068 bytes¡Ahorró la friolera de 12 bytes gracias a Neil!
fuente
"c"+
y escribieras,"c+1 c-1 c*2 c/2|0".split
etc.o=>c=[c+1,c-1,c*2,c/2|0]["+-*/".indexOf(o)]
, o creo que puede continuar para guardar otro byte usandoo=>c={"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o]
?k=>[...k].reduce((c,o)=>+{"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o],0)
podría funcionar aún más corto aún, pero he perdido la cuenta ...}
y[o]
, por lo que en realidad solo tiene 66 bytes de longitud. Además, el OP aclaró;-/
debería devolver -1 , no 0 .Ruby,
484442 + 1 = 43 bytes+1 byte para
-n
bandera. Toma entrada en STDIN.Véalo en ideone (usos
$_
ya que ideone no toma banderas de línea de comando): http://ideone.com/3udQ3Hfuente
PHP 76 bytes
fuente
Python 2,
5856 bytes-2 bytes gracias a @Lynn
Los ordinales de los personajes
+-*/
son43,45,42,47
de módulo 11 son10,1,9,3
de módulo 3 son aquellos1,1,0,0
, 2 menos los que están1,1,2,2
dando las cantidades que necesitamos para cada operación:r=r+1
,r=r-1
,r=r*2
, yr=r/2
Anterior:
fuente
2-ord(c)%11%3
?Mathematica,
837370 bytes10 bytes guardados debido a @MartinEnder .
Función anónima. Toma una lista de caracteres como entrada y devuelve un número como salida. Sugerencias de golf bienvenidas.
fuente
SILOS ,
175164 bytesPruébalo en línea!
Método de entrada sano. División entera correcta (redondeada hacia -infinito).
fuente
C #,
8781 bytesSin golf:
Se supone que la entrada es válida. La división por dos se realiza desplazando un bit hacia la derecha, porque la división regular siempre se redondea hacia cero, y el desplazamiento de bits siempre se reduce. El incremento y la disminución hacen un uso útil de la distancia 1 entre los códigos ASCII para
+
y-
.fuente
int f(string s)=>s.Aggregate(0,(i,c)=>c<43?i*2:c<46?i+44-c:i>>1);
(65 bytes)Javascript (ES6), 57 bytes (matriz) / 60 bytes (entero)
Devolver una matriz de todos los resultados intermedios:
Por ejemplo, la salida para
"++**--/"
será[1, 2, 4, 8, 7, 6, 3]
.Devolviendo solo el resultado final:
Cómo funciona
Ambas soluciones se basan en la misma idea: el uso de la función hash perfecta
eval(2+c+3)&3
para mapear los diferentes caracteres operadoresc
en[0, 3]
.fuente
JavaScript (ES6), 57
Nota: el valor inicial para el acumulador es la cadena del programa, utilizando operaciones de bit (~, >>, <<, |) se convierte a 0 en el primer uso.
Como nota al margen, la respuesta inteligente de @xnor obtendría 40 puntos portados a javascript:
(si te gusta esto, vota por él)
Prueba
fuente
Java, 77 bytes
Utiliza java 8 transmisiones.
fuente
r >> 1
ar>>1
y ahorro 2 bytes?s->s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);
que le dará 56 bytesGNU sed,
655957 bytesEditar: 2 bytes más cortos gracias a los comentarios de Toby Speight
Correr:
Salida:
El
sed
script prepara la entrada para ladc
llamada de shell al final, este último acepta la entrada en notación polaca inversa . En la división, si el número es negativo (d0>
), se llama al[1-]
comando de disminución almacenado en el registro@
. Ejemplo de conversión:+ - * /
->1+ 1- 2* d0>@2/
.fuente
[1-]
patrón ...s
conS
. Olvidé que no reemplaza la pila del registro, lo empuja, teniendo el efecto contrario de lo que quería (ya que lo usé para todos/
). Las comillas todavía son necesarias porque tiene/
símbolos que hacen que la cadena se interprete como una ruta de archivo :) Afeité 1 byte más al eliminar el espacio después de-e
.-e
como un nombre de archivo, por lo que no necesita comillas para el/
- ¡pruébelo! Creo que es razonable que un código de golf requiera que el directorio de trabajo actual no contenga ningún archivo que comience con01s@
o0-s@
.-e
respecto/
, sin embargo, las cotizaciones aún se requieren como acabo de ver ahora. El>
intérprete interpreta directamente el shell como un operador de redireccionamiento, ya que recibí este error:cannot create @2/d0: Directory nonexistent
>
. Necesitas citas, después de todo. ¡Disculpas por (intentar) engañar! Y, aunque agregar una barra diagonal inversa parece un personaje, debe duplicarse en uns///
reemplazo, por lo que no hay beneficio allí ...PHP, 75 bytes
Utiliza una versión modificada de la respuesta de Jörg Hülsermann .
Se basa en gran medida en la sustitución de cadenas, utilizando una expresión regular simple (
~.~
).La variable
$s
se reasigna con el nuevo valor para cada carácter. Al final, genera el resultado.Nota : Esto está destinado a ejecutarse utilizando la
-r
bandera.Pruébalo aquí:
Mostrar fragmento de código
O prueba: http://sandbox.onlinephpfunctions.com/code/7d2adc2a500268c011222d8d953d9b837f2312aa
Diferencias:
echo$s
, estoy usandosprintf($s)
. Ambos realizan la misma acción en números. Como esto es solo para probar, está bien.++*+
como primer argumento, que debería mostrar5
.fuente
e
modificador ha vuelto! : De
, que fue reemplazado porpreg_replace_callback
y podría abusarse de él ... pero esto no es todo eso.Lote, 61 bytes
Traducción de la respuesta de @ xnor's xcellent Python.
fuente
Pyke,
2422 bytesPruébalo aquí!
O 12 bytes (no competitivo)
Pruébalo aquí!
Agregar
translate
nodo: básicamente, buscar y reemplazar múltiplesfuente
PHP,
10410282 bytesPrimera versión con eval:
Segunda versión con operadores ternarios:
Toma la cadena de entrada como primer argumento de la línea de comando.
Este "solo" funciona para cadenas de entrada de menos de 10,000 caracteres, lo que debería ser suficiente. Probado con todos los casos de prueba, desafortunadamente no se puede ahorrar en la inicialización al principio.La segunda versión funciona con cadenas de cualquier longitud y sin inicialización. :-)El elemento principal es la función eval que manipula en
$i
base a un mapa de operaciones aritméticas, que son bastante sencillas excepto por la división. PHP devuelve un flotante cuando se usa/
yintdiv
tiene demasiados bytes, por lo que hacemos un desplazamiento a la derecha .Actualizaciones
$i=$i>>1
de$i>>=1
la división de número entero.fuente
Python 3,
986660 bytesGracias Tukkax!
No es tan elegante como la otra respuesta, pero no puedo competir con ellos sin plagio.
Además, también tengo una solución lambda recursiva
7367 bytes (¡mejorado!)fuente
i=0 for c in input():i+=[1,-i//2,-1,i][ord(c)%23%4] print(i)
. (no formateado correctamente, por supuesto). También creo que deberías mencionar que estás usando Python3. En Python2,input()
evaluaría aint(raw_input())
.+-
hace 1)R, 201 bytes
Golfed
Comentado
La estrategia es refinar los
+, -, %
operadores. Divida la cadena y luego analice la cadena en una larga lista de funciones, para alimentar alReduce()'s
acumulador.No podía seguir jugando al golf. Si alguien puede ponerse
b=body<-
a trabajar, podría haber algunos bytes de ahorro (refine cada función conb
after"-"="+"="/"="*"
). Inicialmente trató de sustituir y analizar eval, pero el orden de las operaciones y los paréntesis fueron aterradores.fuente
f, ...
en la definición de laReduce
función y deshacerse destdin()
enscan
pero yo sólo probado un ingenuo enfoque que dejó caer dos bytes más al definir las funciones de manera un poco diferente. tio.run/##XcvLCsMgEAXQrwnO6Gge29B/…Lex + C,
78,74, 73 bytesEl primer personaje es un espacio.
Lee desde
stdin
, devuelve resultado.Compilar con
lex golfed.l && cc lex.yy.c main.c -lm -lfl
, prueba principal:fuente
Javascript (ES5), 127 bytes
Sin golf:
fuente
Pyth, 23 bytes
Un programa completo que toma la entrada como una cadena e imprime el resultado.
Este es un puerto de la respuesta Python de @ xnor .
Pruébalo en línea
Cómo funciona
fuente
u@[yGhG0tG0/G2)CHQ0
19 bytesPHP, 79 bytes
fuente
1
; necesitas dividir y multiplicar por2