Avalie uma planilha simples

13

Regras

  1. Não há referências de intervalo de células ( A2:B3).

  2. Máximo de 9 linhas e 9 colunas.

  3. Sem referências circulares ou erros de fórmula.

  4. As células vazias são avaliadas como 0.

  5. Os dados são apenas números, mas podem ser tomados como cadeias.

  6. Fórmulas são seqüências de caracteres.

Opções de implementação

Você deve declarar suas escolhas nestes assuntos:

  1. Exija que as fórmulas sejam prefixadas com qualquer caractere único, por exemplo =- ou não.

  2. A célula mais à esquerda da segunda linha é A2ou R2C1, conforme as duas convenções usadas por Excel et al.

  3. Exija qualquer pré ou sufixo de um caractere nas referências de célula, por exemplo $- ou não.

  4. Um de cadeia nula, vazia, lista vazia etc., (mas não 0) para representar células vazias.

  5. Idioma do seu envio (não é permitido o gerenciamento de planilhas).

  6. Idioma para as fórmulas (pode ser diferente do acima). *

  7. Brownie pontos ou cookies para explicar sua solução.

Exemplos

Escolhas: 7 =:; 8 A2:; 9: nenhum; 10 "":; 12: linguagem de fórmula do Excel

Dentro:

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

Fora:

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

Dentro:

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

Fora:

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

Dentro:

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

Fora:

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

Dentro:

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

Fora:

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

* O idioma da fórmula deve ser admissível para PPCG , mas você só precisa oferecer suporte a referências de célula, além dos critérios 3 e 4, wiz. determinação de adição e primidez.

Adão
fonte
A resposta enviada no Excel / VBA não é permitida? Expand array to cells, evaluate.
Urna de polvo mágico
@carusocomputing Se você não está apenas deixando o Excel funcionar, sinta-se à vontade para postar.
Adám 07/04
Podemos ter células baseadas em zero? Como em,R0C0 ?
Conor O'Brien
@ ConorO'Brien Não, deve ser uma das duas convenções usadas por Excel et al.
Adám

Respostas:

6

JavaScript, 125 112 105 bytes

Para usar, adicione f=no início e chame like 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))

Escolhas:

  1. Não requer =.
  2. A célula mais à esquerda da segunda linha é A2.
  3. Não requer nenhum prefixo ou sufixo.
  4. "" (String vazia) para indicar a célula vazia.
  5. JavaScript.
  6. JavaScript.
  7. Biscoitos. 🍪🍪🍪

Explicação:

Esta solução itera sobre todas as células da planilha (cada elemento das sub-matrizes da matriz especificada) e se String não-vazia for encontrada, substitui as referências de célula pelas referências correspondentes em termos da matriz especificada e avalia a expressão com eval()(sim, aquela coisa má que assombra você em seus pesadelos ). Esta solução pressupõe que as constantes fornecidas na matriz de entrada sejam do tipo Inteiro.

Casos de teste

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
fonte
Muito agradável. Aqui: 🍪.
Adám 27/03/17
Algum motivo que você não pode usar /\w\d/gpara o seu regex?
27417 powelles
@powelles também \wcombina dígitos e \d0 também, as duas coisas que você não deseja neste caso. /[A-I][1-9]/gdeve funcionar embora
LarsW 27/03
O @LarsW /\w\d/gproduz exatamente os mesmos resultados nos casos de teste. Também o uso de um literal de modelo na parte eval poderia economizar um punhado de bytes.
27417 powelles
@powelles sim, mas os casos de teste podem estar incompletos. Enfim, eu assumi que as regras escolhidas precisam ser seguidas; mas eles podem ser apenas restrições de entrada (ou ambos), de modo que pode ser o problema também
LarsW
4

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

apresentando array_walk_recursive, uma função anônima recursiva e 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).';');});}

ou

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 na entrada: chamada por referência. Teste online .

  • sem prefixo de expressão
  • formato de referência R2C1, sem prefixo
  • qualquer coisa falsa para célula vazia
  • avalia qualquer expressão PHP (em minúscula), incluindo todas as aritméticas

repartição (primeira versão)

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
fonte
+1 muito bom; 🍪 Você diz aritmética padrão, mas qualquer expressão PHP razoável funcionaria, não?
Adám 27/03
1
@ Adám Agora que você mencionou ... contanto que seja minúsculo, sim. Embora max(range(A1,A3))possa ser confuso. : D
Tito
1
O bom golfe levou muito tempo para encontrar algo: $d=$c;preg_match($x="#[A-Z](.)#",$c=$c[0]para preg_match($x="#[A-Z](.)#",$c=($d=$c)[0]economizar 1 byte.
Christoph
Seria possível incluir um Experimente-o online! ligação?
Adám 28/03/17
1
@ Christoph levou-me uma nova abordagem para corrigir o segundo exemplo ... e salvou um monte no processo ... além de mais de golfe
Titus
3

Mathematica, 119 115 95 bytes

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

Escolhas:

  1. Nenhum prefixo.
  2. R2C1 estilo.
  3. Nenhum prefixo ou sufixo.
  4. "" para células vazias.
  5. Mathematica.
  6. Mathematica. Expressões aritméticas arbitrárias que não usam variáveis ​​do formulário RxCye não têm efeitos colaterais devem funcionar.

Explicação

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

Começamos substituindo todas as cadeias vazias na entrada ( #) por zeros e armazenando o resultado m, porque precisaremos disso novamente em outro local.

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

Substitua repetidamente qualquer sequência restante spelas seguintes ...

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

Combina qualquer substrings da forma RxCyem se substituí-los com ...

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

O que fornece m[[x,y]], o que usa xe ycomo índices na matriz m.

...ToExpression@...

Por fim, avalie essa sequência como uma expressão do Mathematica.

Martin Ender
fonte
Legal. Eu pensei que demoraria um pouco mais do que isso ... Alguma maneira de tentar isso?
Adám 27/03/17
@ Adám Infelizmente, parece não funcionar em matemática, portanto, sem uma cópia do Mathematica, provavelmente não.
Martin Ender
Ainda à espera da construção ...
YSC 27/03
@YSC Excel, 0 bytes.
Adám 27/03/17
@ Adám Isso não estaria competindo de acordo com as regras deste desafio. Além disso, acho que Martin merece um biscoito.
Erik the Outgolfer
2

Clojure, 263 281 bytes

Oh, caramba, sem que apply map vectoro resultado esteja em transposição, como A2é alfabeticamente 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)))))

Exemplos:

(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. Fórmulas são expressões S
  2. A2
  3. Não (+ A1 A2)está bem
  4. nile falsefuncionam como células vazias, mas a cadeia vazia não
  5. Clojure
  6. Expressões S (Clojure + quaisquer macros internas)

Um exemplo de primeira macro de encadeamento:

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

O valor inicial de Cno loop é um mapa de hash, chaves são nomes de células e valores são valores originais. Então todas as referências de células são substituídas pelo conteúdo das células referenciadas até convergirmos ( Previous =C urrent), depois as células são avaliadas e a estrutura plana é particionada novamente em uma lista aninhada.

Seria legal encontrar uma solução onde A1, A2etc. , são realmente funções que (* 2 B2 B3)podem ser chamadas e, em seguida, poderiam ser reescritas (* 2 (B2) (B3))e executadas.

Experimente online!

NikoNyrh
fonte
2

APL (Dyalog) , 51 bytes

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

  2. A2

  3. Nenhum

  4. String vazia

  5. APL

  6. APL

Experimente online!

⍎¨ Avalie cada célula do resultado de

()⍣≡ Aplicação contínua das duas funções a seguir até que nada mais mude

{ primeira função anônima a ser aplicada…

  0 em qualquer
  :: erro:
    retorne o argumento não modificado

   agora tente;

   se a
   contagem do argumento :
  × for positiva,
  : então:
    stringify
    o  argumento
    stringified avaliado
   

   outro;

  0 retornar zero

 … Para cada célula

{ segunda função anônima a ser aplicada…

  '←',¨ Anexar uma seta de atribuição a cada célula do
   argumento

  (),¨ Acrescente o seguinte a cada célula dessa

   1↓ largue o primeiro da
   ⎕D cadeia de todos os D igits (ou seja, zero)

   ⎕A Com todas as letras do A lphabet indo para baixo,
   ∘.,  faça uma tabela de concatenação (com os dígitos restantes indo para a direita)

    transpor (para diminuir números crescentes, letras progressivas corretas)

   ()↑ Pegue a submatriz superior esquerda com o tamanho de…

     o tamanho do
     argumento

} … Para o resultado da função anterior.

Adão
fonte
1
Suas explicações são sempre lindas, obrigado, me faz querer aprender APL além do pouco que sei ao ler essas respostas.
Magic Octopus Urn
@carusocomputing Obrigado. Ficarei feliz em ajudá-lo. Sinta-se à vontade para perguntas e solicitações na sala de bate-papo da APL . Ajudarei você a se preparar também, se precisar.
Adám 07/04
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

Experimente online!

Escolhas:

  1. =

  2. A2

  3. Nenhum

  4. ""

  5. Python 2.7

  6. Expressões Python

Explicação básica:

Para todas as fórmulas da sub-lista, substitua-a pela lista correspondente (ou seja, para o índice B1 s [0] [1]) e avalie o resultado!

  • -4 bytes mudando str () para backticks!
Keerthana Prabhakaran
fonte
Você não adicionou importação de re em sua resposta. Também não passa esta entrada:s=[[ 3, 4,"max(A1,B1)"],[ 2, 5,"A2**B2"],[ "", "","C1+C2"]]
Dead Possum
O formato de entrada é [[ 3, 4,"=max(A1,B1)"],[ 2, 5,"=A2**B2"],[ "", "","=C1+C2"]]Isso existe como parte dos cabeçalhos! Confira no link Experimente!
Keerthana Prabhakaran 28/03
1
Deve ser incluído na contagem de bytes. Basta verificar outras respostas em python neste site
Dead Possum
É isso? Eu sou net to codeglof. Obrigado pelo comentário. Irá adicioná-lo.
Keerthana Prabhakaran 28/03
No que diz respeito às outras respostas, elas não incluíram a entrada! Eu editei com a contagem de bytes de importação!
Keerthana Prabhakaran 28/03