Fundo:
As operações matemáticas padrão, como adição e multiplicação básicas no mundo real, funcionam da seguinte maneira:
12 + 123 = 135
e
12 * 123 = 1476
Isso não é interessante e chato! Muitas escolas já estão interpretando isso como prática, prática, prática de algoritmos formais. Isso implica uma dieta matemática bastante rígida e chata e não é o que se pretende neste desafio. Prepare-se para se divertir um pouco no nosso amado site.
Considere o processo de adicionar dois números inteiros positivos e, em seguida, adicionar novamente todos os dígitos do resultado. Repetindo com a adição até que apenas um dígito seja obtido. Por exemplo:
- O resultado de
12 + 123
é 135. - Adicionando todos os dígitos de 135, obtemos
1 + 3 + 5 = 9
.
O número de etapas necessárias para obter um valor de um dígito 9 nesta adição repetida é 2.
Como no processo anterior da adição, a multiplicação de dois números inteiros positivos segue o mesmo processo. Multiplique todos os dígitos do resultado e, em seguida, repita esse processo até restar apenas um dígito. Veja o exemplo acima:
- O resultado
12 * 123
é 1476. - Multiplique todos os dígitos de 1476 que obtemos
1 * 4 * 7 * 6 = 168
. - Multiplique novamente todos os dígitos de 168 que obtemos
1 * 6 * 8 = 48
. - Multiplique novamente todos os dígitos de 48 que obtemos
4 * 8 = 32
. - Multiplique mais uma vez todos os dígitos de 32 que obtemos
3 * 2 = 6
.
O número de etapas necessárias para obter um valor de um dígito 6 nessa multiplicação repetida é 5.
Para esse desafio e para evitar qualquer uso indevido de notações matemáticas, apresento essas duas notações falsas: (+)
e (*)
, mas você pode usar qualquer notação que desejar , que funciona da seguinte maneira:
- A operação do processo de adição repetida para obter um único valor é
12 (+) 123 = 9
. - A operação do processo de multiplicação repetida para obter um único valor é
12 (*) 123 = 6
.
Desafio:
O desafio é escrever um programa ou uma função que possa executar as duas operações, conforme explicado na seção em segundo plano: (+)
e (*)
.
Entrada:
As entradas do programa ou da função são dois números inteiros positivos e uma operação é (+)
e (*)
. O formato da entrada é uma escolha arbitrária do programador . Você pode formatar a entrada, por exemplo, a (+) b
ou F(a, (+), b)
ou qualquer formato que desejar.
Resultado:
A saída do programa ou da função deve conter o resultado da operação e o número de etapas necessárias com o formato freestyle, conforme desejado.
Casos de teste (ignore o formato de entrada e saída):
81 (+) 31 --> (4 ; 2)
351 (+) 14568 --> (6 ; 3)
21 (*) 111 --> (8 ; 3)
136 (*) 2356 --> (0 ; 2)
Regras gerais:
- Isso é código-golfe , então a resposta mais curta em bytes vence o desafio.
Não permita que a esolangs o desencoraje de postar uma resposta em idiomas comuns. Aproveite esse desafio, fornecendo uma resposta o mais curta possível com sua linguagem de programação. Se você postar uma resposta inteligente e uma explicação clara, sua resposta será apreciada (daí os votos positivos), independentemente da linguagem de programação usada. - As regras padrão se aplicam à sua resposta, para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados, programas completos, etc. A escolha é sua.
- Se possível, seu programa pode lidar adequadamente com grandes números. Caso contrário, tudo ficará bem.
fonte
Respostas:
Dyalog APL ,
33323029 bytesIsso estende o APL para incluir a notação de prefixo
+/A n₁ n₂
e×/A n₁ n₂
. (De fato, você pode usar qualquer operação à esquerda do/A
.) Retorna uma lista de {resultado, número de repetições}.TryAPL online! (
⍎
foi copiadoe
por motivos de segurança.)Agradecemos a @ngn por salvar um byte.
0 bytes (em tom de brincadeira)
O Dyalog APL, na verdade, já tem suporte total para a matemática Anastasiyan; em vez de
(+)
e(×)
, usa+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
e×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
.Tente
81 +{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺e¨⍕⊃⍵}⍣≡⍺⍺/⍺⍵} 31
e21 ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/e¨⍕⍵}⍣=⍵⍺⍺⍨⍺} 111
.fonte
⎕FR←1287
(ou seja, utilizar IEEE 754-2008 128 bits decimal M ponto-loating R ePresentation) e⎕PP←34
(isto é, utilização de 34 caracteres P rint P recision), pode utilizar inteiros abaixo 10³⁴.+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
e×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
ainda muito poucos bytes? Estou confuso sobre como isso é 0 bytes ..: S(+)
seria o Anastasiyan +. O Dyalog APL suporta matemática Anastasiyan, mas usa um glifo de vários caracteres diferente, assim como*
significa poder e você precisa×
multiplicar, enquanto/
significa replicação e÷
divisão.(+)
você ter+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
como entrada, mas como o OP realmente declarou que qualquer formato de entrada serve, você pode usar a função como parâmetro. Hmm, gostaria de saber se isso também é possível em outras linguagens de programação que suportam funções como entrada.Haskell, 108 bytes
Define a função
#
que tem antesa
eb
e então o operadoro
. Curiosidade: isso funciona com qualquer operador (na verdade, qualquer função) que você quiser!fonte
Integer
tipo de Haskell é ilimitado.Pyke, 16 bytes
Experimente aqui!
Toma multiplicar como
B
e adicionar comos
. As duas entradas numéricas são separadas por vírgulas.fonte
JavaScript (ES6), 59
Função recursiva, o formato de entrada é adaptado para simplificar a chamada recursiva:
Teste
fonte
Python 2, 60 bytes
Input é uma string como
81+31
, output é uma tupla de uma string singleton e um contador (por exemplo('4', 2)
,.Teste em Ideone .
fonte
f(['81', '31'],'+')
, mais um byte pode ser salvo, mas que se sente como esticar as regras um pouco longe demais ...operator.add
ouoperator.mul
respectivamente;)Pyth, 16
Toma entrada como
"+ 123 12"
para adição e"* 123 12"
multiplicação. Saídas comoresult<linefeed>steps
.Experimente aqui ou execute um Conjunto de Testes , mas observe que isso depende de avaliação, portanto, apenas a variante de adição funcionará no interpretador online. A multiplicação funciona corretamente com o intérprete offline.
Isso usa a função de redução cumulativa para criar uma lista de resultados intermediários, portanto
"+ 351 14568"
, obtemos[14919, 24, 6]
. Isso funciona porque os números de um dígito são um ponto fixo da adição e multiplicação de Anastasiya. Em seguida, obtemos apenas o último elemento da matriz, bem como o comprimento da matriz.Isso funcionará para números arbitrariamente grandes, pelo menos até você ficar sem memória.
fonte
R,
175167164140134127126119 bytesUngolfed:
ifelse
está de volta ! Sim !Nop
Uso:
Muito obrigado a @plannapus por jogar fora 24 bytes!
-7 bytes graças a uma boa ideia do @Vlo !
fonte
strtoi
! Mais 4 bytes você me derrotou.05AB1E ,
2015 bytesExplicação
Operador é 1 para adição, 0 para multiplicação.
Experimente online
fonte
Geléia ,
1110 bytesEntrada é um par de números e ou
+
ou×
.Experimente online! ou verifique todos os casos de teste .
Como funciona
fonte
Código da máquina ARM, 48 bytes
Despejo hexagonal:
Esta função não depende de nenhuma chamada do sistema ou função de biblioteca. Este é o código Thumb-2, que é uma codificação de instruções de comprimento variável (2 ou 4 bytes) para o ARM de 32 bits. Assim, o valor máximo que ele pode processar é 2 ^ 32-1. 2 bytes podem ser eliminados se não estiverem em conformidade com o AAPCS ( 46 bytes ), pois não teríamos que empilhar registros no início.
Montagem não destruída (sintaxe GNU):
Teste de script em C:
fonte
R,
130124 caracteresUma abordagem um pouco diferente da @ Frédéric 's:
Recuado, com novas linhas:
A linha 4 provavelmente precisa de mais explicações:
Casos de teste:
fonte
f
ser tanto o nome da função e um dos seus argumentos :)Oitava, 85 bytes
MATLAB, 123, 114, 105, 94 bytesDecidiu traduzir isso para a Octace, para aproveitar a indexação direta e aumentar os recursos. Pega a entrada no formulário:,
f(a,operator)
ondea = [number1, number2]
, eoperator==1
fornece o produto eoperator==2
fornece a soma.Explicações:
g={@prod,@sum}{o}
: Escolhe a função, produto ou soma apropriada e a atribui ag
x=g(a)
toma a soma ou o produto das entradasi=1; ... i++
: Incrementador para contar o número de etapasRemovidas duas novas linhas, um espaço e colocadas os dois números de entrada em um vetor, em vez de argumentos separados. Isso economizou 9 bytes, graças ao pajonk! Removido
k=@(x)...
para salvar outros 11 bytes graças ao beaker =) Finalmente, traduzi tudo para o Octave para salvar outros 9 bytes ...fonte
Java,
164159146 bytesO primeiro argumento é apenas o contador, sempre 0
O segundo argumento é o método, 0 para ADD e 1 para MULTIPLY.
O terceiro argumento é uma matriz de Strings, que contém os valores a serem adicionados / multiplicados.
Ungolfed
obrigado a @Kevin Cruijssen por cortar alguns bytes.
graças ao @milk por cortar 5 bytes.
Programa de teste
fonte
m==0
pode serm<1
eInteger.parseInt
pode serInteger.decode
.j
var no final? Inlining(r+"")
duas vezes parece que ele rasparia alguns bytes.Geléia , 17 bytes
Experimente online!
Dados argumentos como
x y 1
esse, calcula a soma de Anastasiyax (+) y
.Dados argumentos como
x y 0
esse, calcula o produto Anastasiyax (*) y
.A saída é dada como
[number of steps, result]
.fonte
Python,
160146129 bytesPostará uma explicação em breve.
A entrada está no formato
12+12
ou5*35
(com normal+
e*
sinais) e assume que esses são os únicos dois operadores.Ele pode lidar com entradas numéricas tão grandes quanto a memória do seu computador permitir.
Estou quase certamente confiante de que isso pode ser mais longe.
EDIT:
1631 bytes salvos graças ao @Copper.fonte
"+" if "+" in s else "*"
para"*+"["+"in s]
e, em vez de atribuí-lot
, basta adicioná-lo em linha naexec
chamada.R, 110 bytes
Usando o divisor do @plannapus.
function(A,F,B){r=Reduce;x=r(F,A,B);y=1;while(x>9){m=nchar(x);x=r(F,x%%10^(1:m)%/%10^(1:m-1));y=y+1};cat(x,y)}
Resultado
editar: eu não posso contar.
fonte
Clojure 126 bytes
A função é chamada assim:
Aqui está o código ungolfed:
Lembre-se de que Clojure ainda é novo para mim, portanto essa provavelmente não é a melhor solução. O desafio foi divertido do mesmo jeito. Além disso, o código foi executado com números muito grandes sem nenhuma dificuldade.
fonte
Perl 6 53 bytes
Como
( 12, &[+], 123 )
é aceitável para a entrada, posso reduzi-lo para 53 bytes.(
&[+]
é a abreviação de&infix:<+>
uma "reverência" ao operador de adição de infixo numérico)Se o segundo argumento tivesse que ser uma string
(+)
, seria de 87 bytesExplicação:
Teste:
Uso normal:
fonte
Python 2,
10797 bytesUma função anônima que recebe entrada via argumento de um primeiro operando
a
, um operadoro
('+'
ou'*'
) e um segundo operandob
e retorna uma lista do formulário[result, steps]
.Como funciona
A função anônima cria uma string concatenando os operandos com o operador entre eles e, em seguida, avalia; este é o primeiro passo descrito na pergunta. Então, esse valor e o operador são passados para a função recursiva
g
. Aqui, um contadori
, que é incrementado para cada chamada recursiva, é usado. Se a entrada for menor que10
, um único dígito deve ter sido alcançado, portanto, issoi
é retornado. Caso contrário, a entrada é convertida em uma string e cada caractere dessa string é associado ao operador, fornecendo o cálculo desejado, que é então avaliado e passado para a função recursivamente.Experimente no Ideone
fonte
Groovy, 102 bytes
Degolfed
Explicação
Baseado na excelente solução do @Sean Bean para Java.
p
: O fechamento (função, lambda, qualquer que seja) que implementa a soluçãot
: A profundidade da chamada atual (número de iterações)p
sempre deve ser chamada comt=1
m
: A operação a ser executada,0
para "adicionar",1
para "multiplicar"d
: A lista de operandos, cada operando é um objeto Stringe
: Os elementos ded
, cada um convertido em um número inteiror
: A soma ou o produto dee
, dependendo da operaçãom
r > 9
:r > 9
), reinicie, aumentando a profundidadet
e convertendor
em uma lista de cadeias de dígitos (e retornando o resultado).r
et
como uma lista.Programa de teste
Resultados
fonte
Haskell,
7670 bytesRetorna uma lista de dois elementos com o resultado e o número de etapas. Funciona para grandes números arbitrários. Exemplo de uso:
(351#14568)(+)
->[6,3]
.Edit: Obrigado a @BlackCap por 6 bytes.
fonte
(-48+).fromEnum
porread.pure
R, 91 bytes
Usando o código do @ Vlo, que faz uso do divisor do @ plannapus, e algumas idéias que eu gerei ao jogar a resposta de @ Frédéric, essa é a resposta R mais curta de todos os tempos. (Um número extraordinariamente grande de respostas R está aqui hoje ...)
Fundamentalmente, isso requer que a entrada do operador seja
sum
para (+) ouprod
para (*). Sob as regras do desafio, isso parece estar bem.Com recuo:
As principais diferenças da resposta da @ Vlo são:
Reduce
, contamos com o argumento de entrada como uma função e apenas o chamamos explicitamente. (Sim, para funções que são objetos de primeira classe!)T
, o que é avaliado comoTRUE
(aka1
), mas como não é uma variável reservada, podemos modificá-la. AssimT+T
é2
. Então, usamos isso como nosso contador.cat
digitar a saída, apenas retornamos como um vetor comc
. Além de salvar dois bytes, o fato de a saída ser forçada em um vetor garante que issoT
seja de classenumeric
. Se usarmoscat
eT
não tivermos sido incrementados, obteremos resultados errados como1 TRUE
.fonte
while
circuito a seguir, mudandoF
para ser outra coisa para conflitos de nome evitar:function(A,O,B){x=O(A,B);while({F=F+1;x>9})x=O(x%/%10^(1:nchar(x)-1)%%10;c(x,F)}}
. É incrível como muitos R truques golfe nós viemos acima com nos últimos anos :)T
andF
counter dentro de uma função é realmente inválido, pois significa que a função pode ser chamada apenas uma vez. Portanto, esta resposta (e várias das minhas outras!) São inválidas, a menos que haja uma explícitarm(T)
no final. Vou continuar procurando essa meta post, para ter certeza de que não sonhei.T
eF
é perfeitamente válido desde que você não modifiqueT
ouF
no ambiente global. por exemplo,f=function(){T=T+1;T}
retorna consistentemente2
. Eu acho que este é o meta post ao qual você se refere.Ruby, 55 bytes
Chamada recursiva. Costumava ser muito diferente da resposta JavaScript do @ edc65, mas como eu o otimizei, eventualmente se tornou uma porta direta desenvolvida quase independentemente da resposta, menos uma otimização final envolvendo a verificação do resultado avaliado em vez do tamanho da lista de operandos passados em , o que me permitiu superar a contagem de bytes.
Input é uma string que representa o operador e uma matriz que contém os operandos.
Experimente online.
fonte
i=0
e eu esqueci ao refatorar.Perl, 38 bytes
Inclui +2 para
-ap
Execute com a entrada STDIN e espaços ao redor do operador:
A saída é um dígito e as etapas são separadas por
+A
amath.pl
:Se a saída das etapas em unário estiver ok, esta versão de 35 bytes funcionará melhor:
fonte
Mathematica,
10594 bytesCódigo.
Uso.
Explicação.
As duas funções
x
(para (+)) ey
(para (*)) são criadas ao mesmo tempo, substituindo os parâmetrosf
eo
emcom seus valores apropriados. Pois
x
,f
torna#1 + #2
-o
se e torna - sePlus
; paray
, eles respectivamente se tornar#1 #2
eTimes
. Reescrevendo a funçãox
para a última parte da explicação:fonte
Java 7,
203195192 bytesEle usa
long
(valor máximo de 2 63 -1). Se fosse utilizadoint
(valor máximo de 2 31 -1), seria apenas 1 byte a menos ( 191 bytes ):Provavelmente pode ser jogado um pouco mais. Porém, ter que imprimir as etapas, bem como a resposta para os dois operadores, leva alguns bytes.
Usa 0 (para
(+)
) e 1 (para(*)
).Ungolfed & código de teste:
Experimente aqui.
Resultado:
fonte