Como refatorar isso em j?
-
21-09-2019 - |
Pergunta
Minha solução novato para projetar Euler #1
+/((0=3|1+i.1000-1) +. (0=5|1+i.1000-1)) * (1+i.1000-1)
Sei que isso pode ser refaturado e transformado em uma função, não sei como fazê -lo e teria que ler todos os laboratórios para aprender.
Solução
Não é necessário "lidar com zero" porque adicionar zero não vai alterar a resposta para que você possa usar i.
Para gerar sua lista de números abaixo de 1000, por exemplo:
i. 10
0 1 2 3 4 5 6 7 8 9
J funciona melhor com as matrizes para que você possa pedir o resíduo (|
) de 3 e 5 ao mesmo tempo, você pode usar a classificação ("
) para controlar como os argumentos são alimentados com resíduos:
3 5 |"0 1 i. 10
0 1 2 0 1 2 0 1 2 0
0 1 2 3 4 0 1 2 3 4
o |"0 1
diz para alimentar o argumento de esquerda para |
An-item-de-um-momento, enquanto alimentava os argumentos corretos, uma linha de vez em vez. Como o argumento certo consiste apenas em uma linha, ele é alimentado repetidamente a cada um dos itens de argumento esquerdo.
Agora podemos fazer o 0=
para toda a matriz:
0 = 3 5 |"0 1 i. 10
1 0 0 1 0 0 1 0 0 1
1 0 0 0 0 1 0 0 0 0
Insira uma condição ou condição entre os dois itens (linhas) da matriz:
+./ 0 = 3 5 |"0 1 i. 10
1 0 0 1 0 1 1 0 0 1
Obtenha o índice de cada 1 na lista/vetor:
I. +./ 0 = 3 5 |"0 1 i. 10
0 3 5 6 9
E soma:
+/ I. +./ 0 = 3 5 |"0 1 i. 10
23
Você pode fazer disso uma função explícita/verbo com bastante facilidade:
euler1=: verb define
+/ I. +./ 0 = 3 5 |"0 1 i. y
)
Ou depois de pegar o jeito do tacit j, você pode definir:
euler1=: +/@I.@(+./)@(0 = 3 5 |"0 1 i.)
Outras dicas
- Refattor
0=
(Will aumenta o tamanho do programa)
+/((3|1+i.1000-1)+.&(0=])5|1+i.1000-1)*1+i.1000-1
- Refattor
1+i.1000-1
+/(((3|])+.&(0=[)5|])1+i.1000-1)*1+i.1000-1
- Refattor
1+i.1000-1
novamente
+/(*(3|])+.&(0=[)5|])1+i.1000-1
A única coisa que eu não conseguia refatorar até agora é o |
operador