Evaluar una hoja de cálculo simple

13

Reglas

  1. No hay referencias de rango de celdas ( A2:B3).

  2. Máximo 9 filas y 9 columnas.

  3. No hay referencias circulares ni errores de fórmula.

  4. Las celdas vacías evalúan a 0.

  5. Los datos son solo números, pero pueden tomarse como cadenas.

  6. Las fórmulas son cadenas.

Opciones de implementación

Debe indicar sus elecciones en estos asuntos:

  1. Exigir que las fórmulas tengan como prefijo cualquier carácter individual, por ejemplo =, o no.

  2. La celda más a la izquierda de la segunda fila es A2o R2C1, según las dos convenciones utilizadas por Excel et al.

  3. Requerir cualquier prefijo o sufijo de un solo carácter en las referencias de celda, por ejemplo $, o no.

  4. Uno de nulo, cadena vacía, lista vacía, etc., (pero no 0) para representar celdas vacías.

  5. Idioma de su envío (los administradores de hojas de cálculo no están permitidos).

  6. Idioma para las fórmulas (puede diferir de lo anterior). *

  7. Brownie puntos o cookies para explicar su solución.

Ejemplos

Opciones: 7 =:; 8 A2:; 9: ninguno; 10 "":; 12: lenguaje de fórmulas de Excel

En:

[[       2, 3],
 ["=A1+B1",""]]

Fuera:

[[2,3],
 [5,0]]

En:

[[       2,"=A1+B2"],
 ["=A1+B1",      ""]]

Fuera:

[[2,2],
 [4,0]]

En:

[[ 3, 4,"=A1*B1"],
 [ 2, 5,"=A2*B2"],
 ["","","=C1+C2"]]

Fuera:

[[3,4,12],
 [2,5,10],
 [0,0,22]]

En:

[["","=2*B2*B3"     ,""],
 [ 3,"=A1+(A2+C2)/2", 2],
 [ 1,"=C1+(A3+C3)/2", 5]]

Fuera:

[[0,15,  0],
 [3, 2.5,2],
 [1, 3  ,5]]

* El lenguaje de la fórmula debe ser PPCG admisible , pero solo debe admitir referencias de celda más los criterios 3 y 4 allí, por ejemplo. Además y determinación de primacía.

Adán
fuente
¿Se ha enviado una respuesta en Excel / VBA no permitido? Expand array to cells, evaluate.
Magic Octopus Urn
@carusocomputing Si no solo está dejando que Excel haga lo suyo, no dude en publicar.
Adám
¿Podemos tener células basadas en cero? Como en R0C0?
Conor O'Brien
@ ConorO'Brien No, tiene que ser una de las dos convenciones utilizadas por Excel et al.
Adám

Respuestas:

6

JavaScript 125 112 105 bytes

Para usar, agregue f=al principio e invoque como f(argument).

a=>a.map(b=>b.map(p=>+p?p:p?eval(p.replace(/[A-I][1-9]/g,m=>`a[${m[1]-1}][${(m.charCodeAt(0)-65)}]`)):0))

Opciones:

  1. No requiere =.
  2. La celda más a la izquierda de la segunda fila es A2.
  3. No requiere ningún prefijo o sufijo.
  4. "" (Cadena vacía) para denotar la celda vacía.
  5. JavaScript
  6. JavaScript
  7. Galletas. 🍪🍪🍪

Explicación:

Esta solución itera sobre todas las celdas de la hoja de trabajo (cada elemento de las sub-matrices de la matriz dada) y si se encuentra una Cadena no vacía, reemplaza sus referencias de celda con las referencias correspondientes en términos de la matriz dada y evalúa la expresión con eval()(sí, esa cosa malvada que te persigue en tus pesadillas ). Esta solución supone que las constantes proporcionadas en la matriz de entrada son de tipo entero.

Casos de prueba

f=a=>a.map(b=>b.map(p=>+p?p:p?eval(p.replace(/[A-I][1-9]/g,m=>`a[${m[1]-1}][${(m.charCodeAt(0)-65)}]`)):0))

console.log(f([[1,2,3],["A1+B1+C1",10,11]]));
console.log(f([[1,2,5,4,6,89,0],[0,1,2,3,"A2+A1",5,6]]));
console.log(f([[1,2,4,5],["A1/B1*C1+A1+Math.pow(5,B1)",2,3,4]]));

Arjun
fuente
Muy agradable. Aquí: 🍪.
Adám
¿Alguna razón que no puedas usar /\w\d/gpara tu expresión regular?
Powelles
@powelles también \wcoincide con los dígitos y \dtambién con 0, ambas cosas que no quieres en este caso. /[A-I][1-9]/gaunque debería funcionar
LarsW
@LarsW /\w\d/gproduce exactamente los mismos resultados en los casos de prueba. Además, usar un literal de plantilla en la porción eval podría ahorrar un puñado de bytes.
powelles
@powelles sí, pero los casos de prueba pueden estar incompletos. De todos modos, asumí que las reglas elegidas deben seguirse; pero pueden ser solo restricciones de entrada (o ambas), por lo que ese también puede ser el problema
LarsW
4

PHP, 265 263 259 258 257 240 224 222 213 202 196 bytes

presentando array_walk_recursive, una función anónima recursiva y preg_replace_callback:

function f(&$a){array_walk_recursive($a,$p=function(&$c)use($a,&$p){eval('$c='.preg_replace_callback("#R(.)C(.)#",function($m)use($a,&$p){$d=$a[$m[1]-1][$m[2]-1];$p($d);return$d;},$c?:0).';');});}

o

function f(&$a){array_walk_recursive($a,$p=function(&$c)use($a,&$p){eval('$c='.preg_replace_callback("#R(.)C(.)#",function($m)use($a,&$p){return$p($a[$m[1]-1][$m[2]-1]);},$c?:0).';');return$c;});}

opera en entrada: llamada por referencia. Pruébelo en línea .

  • sin prefijo de expresión
  • formato de referencia R2C1, sin prefijo
  • nada falso para celda vacía
  • evalúa cualquier expresión PHP (en minúsculas), incluida toda la aritmética

desglose (primera versión)

function f(&$a)
{
    array_walk_recursive($a,                    # walk through elements ...
        $p=function(&$c)use($a,&$p){            # use array $a and recursive $p
            eval('$c='.                             # 3. evaluate expression
                preg_replace_callback('#R(.)C(.)#', # 2. replace references with ...
                function($m)use($a,&$p){
                    $d=$a[$m[1]-1][$m[2]-1];            # $d=content of referenced cell
                    $p($d);                             # recursive evaluation
                    return$d;                           # return $d
                },$c?:0)                            # 1. replace empty with 0
                .';'
            );
        }
    );
}
Titus
fuente
+1 Muy agradable; 🍪. Dices aritmética estándar, pero realmente cualquier expresión PHP razonable funcionaría, ¿no?
Adám
1
@ Adám Ahora que lo mencionas ... siempre y cuando sea minúscula, sí. Aunque max(range(A1,A3))puede ser confuso. : D
Tito
1
Bonito campo me tomó bastante tiempo para encontrar cualquier cosa: $d=$c;preg_match($x="#[A-Z](.)#",$c=$c[0]a preg_match($x="#[A-Z](.)#",$c=($d=$c)[0]debe guardar 1 byte.
Christoph
¿Sería posible incluir un Probar en línea! ¿enlace?
Adám
1
@Christoph me tomó un nuevo enfoque para arreglar el segundo ejemplo ... y ahorró mucho en el proceso ... además de jugar al golf más
Titus
3

Mathematica, 119 115 95 bytes

(m=#/.""->0)//.s_String:>ToExpression@StringReplace[s,"R"~~x_~~"C"~~y_:>"m[["<>{x,",",y,"]]"}]&

Opciones:

  1. Sin prefijo
  2. R2C1 estilo.
  3. Sin prefijo o sufijo.
  4. "" para celdas vacías.
  5. Mathematica
  6. Mathematica Las expresiones aritméticas arbitrarias que no usan variables de la forma RxCyy no tienen efectos secundarios deberían funcionar.

Explicación

(m=#/.""->0)

Comenzamos reemplazando todas las cadenas vacías en la entrada ( #) con ceros y almacenando el resultado m, porque lo necesitaremos nuevamente en otro lugar.

...//.s_String:>...

Reemplace repetidamente cualquier cadena restante scon lo siguiente ...

...StringReplace[s,"R"~~x_~~"C"~~y_:>...]

Coincide cualquier subcadenas de la forma RxCyen sy reemplazarlos con ...

..."m[["<>{x,",",y,"]]"}

Que da m[[x,y]], que usa xy ycomo índices en la matriz m.

...ToExpression@...

Finallz, evalúa esta cadena como una expresión de Mathematica.

Martin Ender
fuente
Frio. Pensé que tomaría un poco más de tiempo ... ¿Alguna forma de intentar esto?
Adám
@ Adám Desafortunadamente, no parece funcionar en matemáticas, por lo que sin una copia de Mathematica, probablemente no.
Martin Ender
Todavía
estoy
@YSC Excel, 0 bytes.
Adám
@ Adám Eso no estaría compitiendo según las reglas de este desafío. Además, creo que Martin merece una galleta.
Erik the Outgolfer
2

Clojure, 263 281 bytes

Oh, maldita sea, sin eso, apply map vectorel resultado está en transposición, como A2está alfabéticamente antes B1.

#(apply map vector(partition(count(% 1))(for[v(vals(loop[C(into{}(mapcat(fn[i r](map(fn[j v][(str j i)(or v"0")])"ABCDEFGHI"r))(rest(range))%))P[]](if(= C P)C(recur(into(sorted-map)(for[[k v]C][k(reduce(fn[r[K V]](clojure.string/replace r K V))v C)]))C))))](eval(read-string v)))))

Ejemplos:

(def f #(...))

(f [["2" "3"]["(+ A1 B1)" nil]])
([2 3] [5 0])

(f [[nil ,"(* 2 B2 B3)"                ,nil],
    ["3" ,"(+ A1 (/ (+ A2 C2) 2))"     ,"2"],
    ["1" ,"(-> A3 (+ C3) (/ 2) (+ C1))","5"]])
([0 15N 0] [3 5/2 2] [1 3 5])
  1. Las fórmulas son expresiones S
  2. A2
  3. No (+ A1 A2)esta bien
  4. nily falsefuncionan como celdas vacías, pero la cadena vacía no
  5. Clojure
  6. Expresiones S (Clojure + cualquier macro incorporada)

Un ejemplo de hilo primera macro:

(macroexpand '(-> A3 (+ C3) (/ 2) (+ C1)))
(+ (/ (+ A3 C3) 2) C1)

El valor inicial de Cen el bucle es un mapa hash, las claves son nombres de celda y los valores son valores originales. Luego, todas las referencias de celda se reemplazan por el contenido de las celdas referenciadas hasta que hayamos convergido ( Previous = Current), luego se evalúan las celdas y la estructura plana se divide nuevamente en una lista anidada.

Sería genial encontrar una solución donde A1, A2etc., en realidad son funciones invocables, que luego (* 2 B2 B3)podrían reescribirse (* 2 (B2) (B3))y ejecutarse.

Pruébalo en línea!

NikoNyrh
fuente
2

APL (Dyalog) , 51 bytes

⍎¨({((⍴⍵)↑⍉⎕A∘.,1↓⎕D),¨'←',¨⍵}{0::⍵⋄×≢⍵:⍕⍎⍕⍵⋄0}¨)⍣≡
  1. Ninguna

  2. A2

  3. Ninguna

  4. Cuerda vacía

  5. APL

  6. APL

Pruébalo en línea!

⍎¨ Evaluar cada celda del resultado de

(... )⍣≡ aplicación continua de las siguientes dos funciones hasta que nada más cambie

{ primera función anónima que se aplicará ...

  0 en cualquier
  :: error:
    devuelve el argumento sin modificar

   ahora intenta;

   si el
   conteo del argumento :
  × es positivo,
  : entonces:
    stringify
    el  argumento
    stringified evaluado
   

   más;

  0 devolver cero

 ... a cada celda

{ segunda función anónima que se aplicará ...

  '←',¨ anteponer una flecha de asignación a cada celda del
   argumento

  (... ),¨ anteponga lo siguiente a cada celda de ese

   1↓ suelte el primero de
   ⎕D la cadena de todos los D igits (es decir, cero)

   ⎕A Con todas las letras del alfabeto A bajando,
   ∘., haga una tabla de concatenación (con los dígitos restantes a la derecha)

    transposición (para obtener números cada vez mayores, letras progresivas correctas)

   (... )↑ tome la submatriz superior izquierda con el tamaño de ...

     el tamaño del
     argumento

} ... al resultado de la función anterior.

Adán
fuente
1
Sus explicaciones siempre son hermosas, gracias, me dan ganas de aprender APL más allá de lo poco que sé al leer estas respuestas.
Urna mágica del pulpo
@carusocomputing Gracias. Estaré encantado de ayudarte. Siéntase libre de preguntas y solicitudes en la sala de chat de APL . También te ayudaré a prepararte si lo necesitas.
Adám
1

Python 2 273,265,263 , 259 bytes

import re
def g(m):x=m.group();return's[%d][%d]'%(int(x[1])-1,ord(x[0])-65)
e=enumerate
while'='in`s`:
    for x,i in e(s):
        for i,j in e(i):
            try:s[x][i]=0if not j else float(eval(re.sub('\w\d',g,str(j)).strip('=')))
            except:pass

Pruébalo en línea!

Opciones:

  1. =

  2. A2

  3. ninguna

  4. ""

  5. Python 2.7

  6. Expresiones de Python

Explicación básica:

Para cada fórmula en la sublista, sustitúyala con el índice de la lista correspondiente (es decir, para B1 s [0] [1]) y evalúe el resultado.

  • -4 bytes cambiando str () a backticks!
Keerthana Prabhakaran
fuente
No agregó importación de re en su respuesta. Tampoco pasa esta entrada:s=[[ 3, 4,"max(A1,B1)"],[ 2, 5,"A2**B2"],[ "", "","C1+C2"]]
Dead Possum
El formato de entrada es ¡ [[ 3, 4,"=max(A1,B1)"],[ 2, 5,"=A2**B2"],[ "", "","=C1+C2"]]Eso está ahí como parte de los encabezados! ¡Compruébalo en el enlace de prueba en línea!
Keerthana Prabhakaran
1
Debe incluirse en el recuento de bytes. Sólo echa un vistazo otras respuestas Python en este sitio
Dead Possum
¿Lo es? Soy neto para codeglof. Gracias por el comentario. Lo agregaré.
Keerthana Prabhakaran
En lo que respecta a las otras respuestas, ¡no han incluido la entrada! ¡He editado con el bye count de importación!
Keerthana Prabhakaran