Comment fonctionnent les mathématiques dans le monde d'Anastasiya?

44

Contexte:

Les opérations standard comme l’addition et la multiplication de base dans le monde réel fonctionnent comme suit:

12 + 123 = 135

et

12 * 123 = 1476

Ce n'est pas intéressant et ennuyeux! Beaucoup d'écoles interprètent déjà cela comme pratique, pratique, pratique d'algorithmes formels. Cela implique un régime mathématique mathématique assez rigide et ennuyeux et n’est pas ce que l’on envisage dans ce défi. Préparez-vous à vous amuser sur notre site bien-aimé.

Considérons le processus d’ajout de deux nombres entiers positifs, puis l’ajout de tous les chiffres du résultat. Répéter avec l'addition jusqu'à obtenir un seul chiffre. Par exemple:

  1. Le résultat de 12 + 123est 135.
  2. En ajoutant tous les chiffres de 135, nous obtenons 1 + 3 + 5 = 9.

Le nombre d'étapes requis pour obtenir une valeur à un chiffre 9 dans cette addition répétée est égal à 2.

Comme avec le processus précédent de l'addition, la multiplication de deux nombres entiers positifs suit le même processus. Multipliez tous les chiffres de son résultat, puis répétez ce processus jusqu'à ce qu'il ne reste qu'un seul chiffre. Prenons l'exemple ci-dessus:

  1. Le résultat de 12 * 123est 1476.
  2. Multipliez tous les chiffres de 1476 que nous obtenons 1 * 4 * 7 * 6 = 168.
  3. Multiplie encore tous les chiffres de 168 que nous obtenons 1 * 6 * 8 = 48.
  4. Multiplie encore tous les chiffres de 48 que nous obtenons 4 * 8 = 32.
  5. Multiplie encore tous les chiffres de 32 obtenus 3 * 2 = 6.

Le nombre d'étapes requis pour obtenir une valeur à un chiffre 6 cette multiplication répétée est 5.

Par souci de ce défi et en évitant toute utilisation abusive des notations mathématiques, je vous présente ces deux notations factices: (+)et (*), mais vous pouvez utiliser la notation de votre choix , qui fonctionne comme suit:

  1. L'opération du processus d'addition répétée pour obtenir une valeur unique est 12 (+) 123 = 9.
  2. L'opération du processus de multiplication répétée pour obtenir une valeur unique est 12 (*) 123 = 6.

Défi:

Le défi consiste à écrire un programme ou une fonction pouvant exécuter les deux opérations décrites dans la section Arrière-plan: (+)et (*).

Contribution:

Les entrées du programme ou de la fonction sont deux entiers positifs et une opération soit (+)et (*). Le format de l'entrée est un choix arbitraire du programmeur . Vous pouvez formater l'entrée, par exemple, a (+) bou F(a, (+), b)ou tout autre format de votre choix.

Sortie:

La sortie du programme ou de la fonction doit contenir le résultat de l'opération et le nombre d'étapes requises avec le format freestyle que vous le souhaitez.

Cas de test (ignorer les formats d'entrée et de sortie):

    81 (+) 31       -->   (4 ; 2)
    351 (+) 14568   -->   (6 ; 3)
    21 (*) 111      -->   (8 ; 3)
    136 (*) 2356    -->   (0 ; 2)

Règles générales:

  • C'est du , donc la réponse la plus courte en octets remporte le défi.
    Ne laissez pas les esolangs vous dissuader de poster une réponse dans des langues normales. Profitez de ce défi en fournissant une réponse aussi courte que possible avec votre langage de programmation. Si vous postez une réponse intelligente et une explication claire, votre réponse sera appréciée (d'où les votes positifs) quel que soit le langage de programmation que vous utilisez.
  • Les règles standard s'appliquent à votre réponse. Vous êtes donc autorisé à utiliser STDIN / STDOUT, fonctions / méthode avec les paramètres appropriés, programmes complets, etc. Vous avez le choix.
  • Si possible, votre programme peut gérer correctement les grands nombres. Sinon, ça ira.

Que le jeu commence!!

Anastasiya-Romanova
la source
La partie addition répétée ( racine numérique ) est essentiellement une copie de codegolf.stackexchange.com/q/1128/194
Peter Taylor
4
Super première question! Et je reconnais le format des règles générales et les phrases de mes propres questions. ;)
Kevin Cruijssen
4
@ KevinCruijssen Yup. C'est vrai. Puisqu'il n'a pas de copyright, je le duplique sans votre permission. Hehehe: D
Anastasiya-Romanova 秀
4
@ Anastasiya-Romanova 秀 "pas de droit d'auteur"? Au XXIème siècle? Nan; tout ici est CC-BY-SA 3.0. L'autorisation est accordée lorsque le contenu est soumis. Vérifiez le pied de page du site.
Mindwin
1
@ BradGilbertb2gills Oui, bien sûr. C'est d'ailleurs indiqué dans le message. Citation: "Le format de l'entrée est un choix arbitraire du programmeur".
Anastasiya-Romanova

Réponses:

11

Dyalog APL , 33 32 30 29 octets

Cela étend APL pour inclure la notation de préfixe +/A n₁ n₂et ×/A n₁ n₂. (En fait, vous pouvez utiliser n’importe quelle opération à gauche de /A.) Renvoie une liste de {résultat, nombre de répétitions}.

A←{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺⍎¨⍕⊃⍵}⍣≡⍺⍺⍵}

A←{définir une fonction d'ordre supérieur en termes de fonction de gauche ⍺⍺et d'argument de droite

(⊃,≢) le premier élément de, suivi du compte de

⍺⍺{la fonction fournie ( +/pour somme ou ×/pour produit) introduite dans la fonction d'ordre supérieur

les éléments uniques de

⍵,⍨ l'argument annexé à

⍺⍺ la fonction alimentée appliquée à

⍎¨ l'évaluation de chaque caractère de

la représentation du personnage de

⊃⍵ le premier élément de l'argument

}⍣≡ appliqué à plusieurs reprises jusqu'à ce que le résultat soit identique à l'argument, en commençant par

⍺⍺⍵la fonction alimentée à l'origine ( +/ou ×/) appliquée à l'argument d'origine

} [fin de la définition de fonction d'ordre supérieur]

TryAPL en ligne! ( a été imité avec epour des raisons de sécurité.)

Merci à @ ngn d'avoir sauvegardé un octet.


0 octet (en plaisanterie)

Dyalog APL prend déjà en charge les mathématiques Anastasiyan; au lieu de (+)et (×), il utilise +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}et ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}.

Essayez 81 +{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺e¨⍕⊃⍵}⍣≡⍺⍺/⍺⍵} 31et 21 ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/e¨⍕⍵}⍣=⍵⍺⍺⍨⍺} 111.

Adam
la source
Merci pour la réponse, (+1). Peut-il gérer des entrées de grand nombre?
Commentaires
1
Si vous définissez ⎕FR←1287(utilisez IEEE 754-2008 128 bits décimal F loating point R ePresentation) et ⎕PP←34(utilisation 34 caractères P Rint P recision), vous pouvez utiliser des entiers ci - dessous 10³⁴.
Adám
Hmm, même si elle a le soutien complet, ne sont pas +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}et ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}encore tout à fait quelques octets? Je suis confus à propos de la façon dont il s'agit de 0 octets ..: S
Kevin Cruijssen
3
@KevinCruijssen L'OP permet n'importe quelle notation d'entrée. Ainsi, si une langue prenait en charge les mathématiques Anastasiyan avec la notation par défaut prête à l'emploi, le glyphe à caractères multiples (+)serait l'Anastasiyan +. Dyalog APL prend en charge les mathématiques Anastasiyan, mais il utilise un glyphe différent à plusieurs caractères, tout comme la *puissance et vous avez besoin ×pour la multiplication, tandis /que la réplication et le besoin ÷pour la division.
Adám
1
@ Adám Ah ok, c'est logique. C'est un peu comme plier les règles de l'OP, mais pas les enfreindre. Il est toujours assez étrange qu’au lieu de (+)vous en avoir une +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}entrée, mais puisque OP a effectivement indiqué que tout format d’entrée ferait l'affaire, vous pouvez utiliser la fonction en tant que paramètre. Hmm, je me demande si cela est également possible dans d'autres langages de programmation qui prennent en charge les fonctions en entrée.
Kevin Cruijssen
8

Haskell, 108 octets

f=map(read.pure).show
g h=(\x->(h.f$last x,length x+1)).takeWhile(>10).iterate(h.f)
(a#b)o=g(foldr1 o)$o a b

Définit la fonction #qui prend d' abord aet bpuis l'opérateur o. Fait amusant: cela fonctionne avec n'importe quel opérateur (en fait, n'importe quelle fonction) que vous voulez!

ThreeFx
la source
Merci pour la réponse, (+1). Peut-il gérer des entrées de grand nombre?
Commentaires
4
@ Anastasiya-Romanova 秀 Oui, il peut gérer des nombres aussi grands que votre RAM car le Integertype de Haskell est illimité.
ThreeFx
8

Pyke, 16 octets

RE`DltImbRoKr)oh

Essayez-le ici!

RE               - evaluate the input as Pyke code
                 -  (`B` is product and `s` is sum, the second line is a tuple)
  `              - i = str(^)
    ltI      )   - if len(i) != 1:
       mb        -   map(i, int)
         R       -   get the `B` or `s` from input
          oK     -   o++
            r    -   goto_start()
              oh - o++ + 1

Prend se multiplier comme Bet ajouter comme s. Les deux entrées numériques sont séparées par des virgules.

Bleu
la source
1
Agréable! Pouvons-nous avoir une explication?
Emigna
Merci pour la réponse, (+1). Peut-il gérer des entrées de grand nombre?
Commentaires
@ Anastasiya-Romanova 秀 il devrait être capable de gérer des nombres arbitraires
Bleu
Je ne peux pas tester votre code car le Web est bloqué car il enfreint les règles d'utilisation d'Internet de mes parents. T_T
Anastasiya-Romanova
Quelque chose comme ça: Page Web bloquée! Vous avez essayé d'accéder à une page Web en violation de votre politique d'utilisation d'Internet. URL: pyke.catbus.co.uk/?code=RE%60DltImbRoKr%29oh&input=B%0A21%2C+111&warnings=0 Catégorie: Non évalué
Anastasiya-Romanova 秀
8

JavaScript (ES6), 59

Fonction récursive, le format de saisie est conçu pour simplifier l'appel récursif:

  • opérateur: '+' ou '*'
  • opérandes: tableau de deux valeurs
f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

Tester

f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

;[
  [81,'+',31,     /* -> */ 4, 2]
, [351,'+',14568, /* -> */ 6, 3]
, [21,'*',111,    /* -> */ 8, 3]
, [136,'*',2356,  /* -> */ 0, 2]
].forEach(t=>{
  var [a,o,b,k1,k2] = t,
      [r,s]=f(o,[a,b]);
  console.log(k1==r && k2==s ? 'OK':'KO',a,o,b,'->',r,s)
})  
  

edc65
la source
Merci pour la réponse, (+1). Peut-il gérer des entrées de grand nombre?
Commentaires
1
@ Anastasiya-Romanova 秀 jusqu'à la limite du format numérique javascript, précision de 53 bits (17 chiffres décimaux)
edc65
8

Python 2, 60 octets

f=lambda s,c=0:s[1:]and f(min(s).join(`eval(s)`),c+1)or(s,c)

L' entrée est une chaîne du type 81+31, la sortie est un tuple d'une chaîne de singleton et un compteur (par exemple, ('4', 2).

Testez-le sur Ideone .

Dennis
la source
Si la saisie est un tableau de chaînes et qu'une seule chaîne est autorisée, f(['81', '31'],'+')un octet supplémentaire peut être sauvegardé, mais cela donne l'impression d'étirer un peu trop les règles ...
Dennis
... Dans ce cas, j'irais même autant loin et envisagerais de passer operator.addou operator.mulrespectivement;)
Tobias Kienzler
7

Pyth, 16

eJ.uvjhQ`N.vQ)lJ

Prend les entrées comme "+ 123 12"pour l'addition et "* 123 12"pour la multiplication. Les sorties aiment result<linefeed>steps.

Essayez-le ici ou lancez une suite de tests , mais notez que cela dépend de eval, de sorte que seule la variante d’addition fonctionnera dans l’interprète en ligne. La multiplication fonctionne correctement avec l'interpréteur hors ligne.

Ceci utilise la fonction de réduction cumulative pour créer une liste de résultats intermédiaires, donc pour "+ 351 14568"nous [14919, 24, 6]. Cela fonctionne car les nombres à un chiffre sont un point fixe de l'addition et de la multiplication d'Anastasiya. Ensuite, nous obtenons juste le dernier élément du tableau ainsi que la longueur du tableau.

Cela fonctionnera pour des nombres arbitrairement grands, au moins jusqu'à ce que vous manquiez de mémoire.

FryAmTheEggman
la source
7

R, 175 167 164 140 134 127 127 126 119 octets

function(G,S,D){i=1;O=switch(S,"+"=sum,prod);x=O(G,D);while(x>9){i=i+1;x=O(strtoi(strsplit(paste(x),"")[[1]]))};c(x,i)}

Ungolfed:

f=function(G,S,D) #The function takes : the left operand, the operation symbol (between quote marks)
                  #and then the right operand
i=1               #That's the counter

O=switch(S,"+"=sum,prod)     #`O` takes the value `sum` if `S` matches `+`, `prod` 
                             #(which is the next agument) if not. 

x=O(G,D)                     #Does the first operation

while(nchar(x)>1)                 #While the number of character of the result 
                                  #of the operation is not of length 1, i.e., an integer :

    i=i+1                                    #Increase the counter
    x=O(strtoi(strsplit(paste(x),"")[[1]]))  #Apply the operation `O` to the first operation and 
                                             #the eventual subsequent ones

c(x,i)                                 #Outputs the result and the counter

ifelseest de retour ! Ouais !
Nop

Utilisation:

Special addition
> f(31,"+",81)
[1] 4 2

Special multiplication
> f(136,"*",2356)
[1] 0 2

Merci beaucoup à @plannapus pour avoir joué 24 octets!
-7 octets grâce à une bonne idée de @Vlo !

Frédéric
la source
Oui, merci d’ajouter des explications car j’aime R! C'est ma deuxième langue après VBA. (+1)
Anastasiya-Romanova
1
@ Anastasiya-Romanova 秀: Fait!
Frédéric
@plannapus: vraiment sympa! Merci beaucoup !
Frédéric
1
@ Frédéric belle utilisation de strtoi! 4 octets de plus vous me faites battre.
Plannapus
1
On dirait que vous pouvez continuer à jouer au-delà d'un octet en incluant la définition de O dans l'attribution de x lors de la première opération: x = (O = commutateur (S, somme, `*`)) (G, D) ;.
rturnbull
6

05AB1E , 20 15 octets

[¼¹iOëP}Dg#S]¾‚

Explication

[       Dg# ]    # loop until number is single digit
 ¼               # increase counter
  ¹iO            # if operation is addition, sum list
     ëP}         # else take product of list
           S     # split into a list of digits
             ¾‚  # pair final number with counter and output

L'opérateur est 1 pour l'addition, 0 pour la multiplication.

Essayez-le en ligne

Emigna
la source
Merci pour la réponse, (+1). Peut-il gérer des entrées de grand nombre?
Commentaires
@ Anastasiya-Romanova 秀 Je ne vois pas pourquoi. Avez-vous un exemple?
Emigna
Votre programme a été testé pour ce type d'entrées, il est donc parfait :)
Anastasiya-Romanova
6

Gelée , 11 à 10 octets

Dj⁹VµÐĿḊĖṪ

L'entrée est une paire de nombres et soit +ou ×.

Essayez-le en ligne! ou vérifier tous les cas de test .

Comment ça marche

Dj⁹VµÐĿḊĖṪ  Main link. Left argument: [x, y] (integers). Right argument: + or ×

    µÐĿ     Repeatedly execute the chain to the left, initially with argument
            [x, y], then with the previous return value. Stop when the results are
            no longer unique, and return the array of all intermediate results.
D           Decimal; convert the integers [x, y] or the return value z to base 10.
 j⁹         Join, separating by the link's right argument, i.e., '+' or '×'.
   V        Evaluate the result. This casts the previous return value to string,
            so, e.g., [8, 1, '+', 3, 1] becomes "81+31" before evaluation.
       Ḋ    Dequeue; discard the first intermediate result, i.e., [x, y].
        Ė   Enumerate; prefix each integer in the array with its 1-based index.
         Ṫ  Tail; extract the last index-value pair.
Dennis
la source
6

Code machine ARM, 48 octets

Décharge Hex:

b570 2a00 bf0c 1840 4348 2101 230a e00c 3101 0015 fbb0 f6f3 fb06 0413 2a00 bf0c 192d 4365 0030 d1f5 0028 280a d2f0 bd70

Cette fonction ne dépend d'aucun appel système ni d'aucune fonction de bibliothèque. C'est le code Thumb-2, qui est un codage d'instruction de longueur variable (2 ou 4 octets) pour ARM 32 bits. Ainsi, la valeur maximale qu'il peut traiter est 2 ^ 32-1. 2 octets pourraient être supprimés s'ils n'étaient pas conformes à l'AAPCS ( 46 octets ), car nous n'aurions pas à empiler les registres au début.

Ungolfed assembly (syntaxe GNU):

.syntax unified
.text
.global anastasiya
.thumb_func
anastasiya:
    @Input:
    @r0 - First number
    @r1 - Second number
    @r2 - 0 for add, 1 for multiply
    @Output:
    @r0 - Resultant value
    @r1 - Number of steps
    push {r4,r5,r6,lr}
    cmp r2,#0
    ite eq @if r2==0
    addeq r0,r0,r1 @r0+=r1
    mulne r0,r0,r1 @else r0*=r1
    movs r1,#1 @r1 is the number of steps
    movs r3,#10
    b endloop
    loop:
        adds r1,r1,#1 @Increment number of steps
        movs r5,r2 @r5=1 if multiply, 0 if add
        parseDigits:
            udiv r6,r0,r3 @r6=r0/r3
            mls r4,r6,r3,r0 @r4=r0 - r6*r3
            @Last two operations were r4=r0%r3 (r3==10)
            cmp r2,#0
            ite eq @if r2==0
            addeq r5,r5,r4 @r5+=r4
            mulne r5,r5,r4 @else r5*=r4
            movs r0,r6 @r0=r6 (Set r0 to r0/10)
            bne parseDigits @while (r0!=0)
        @Now our new total is in r5
        movs r0,r5 @Put it in r0
    endloop:
        cmp r0,#10
        bhs loop @while (r0 >=10)
    pop {r4,r5,r6,pc} @Return

Test de script en C:

#include <stdio.h>
unsigned long long anastasiya(unsigned,unsigned,unsigned);

int main(void) {
    unsigned x,y,op;
    printf("Enter first operand, second operand, and 0 for addition or 1 for multiplication.\n");
    scanf("%u%u%u",&x,&y,&op);
    unsigned long long res = anastasiya(x,y,op);
    printf("Result = %u, steps = %u\n",(unsigned)res ,(unsigned)(res >> 32));
}
Ian Chew
la source
4

R, 130 124 caractères

Une approche quelque peu différente de celle de @ Frédéric :

f=function(a,f,b){b=c(a,b);n=1;while((m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1){b=d%%10^(1:m)%/%10^(1:m-1);n=n+1};c(d,n)}

Indenté, avec nouvelles lignes:

f=function(a,f,b){
    b=c(a,b) # Take both numbers
    n=1 #Counter
    while((m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1){
#My own special digit splitter! (d is the result and m is the nb of char of d)
        b=d%%10^(1:m)%/%10^(1:m-1)
        n=n+1
    }
    c(d,n) #Print results
    }

La ligne 4 a probablement besoin de plus d'explications:

switch(f,'(+)'=sum,prod) #pick which operator to use
switch(f,'(+)'=sum,prod)(b) # apply it to b
d<-switch(f,'(+)'=sum,prod)(b) #Saves the result in d
nchar(d<-switch(f,'(+)'=sum,prod)(b))#Measures the number of character of d
m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)) #Saves it in m
(m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1 #Checks if it is more than 1

Cas de test:

> f(12,"(+)",123)
[1] 9 2
> f(12,"(*)",123)
[1] 6 5
> f(351,"(+)",14568)
[1] 6 3
planificateur
la source
Assez malheureux, vous êtes arrivé en retard avec cette réponse, mais vous avez mon vote positif. Merci d'avoir créé cela dans R.
Anastasiya-Romanova 秀
Pourquoi malheureux?
Plannapus
Parce que si vous étiez venu en premier, alors vous auriez plus de votes positifs
Anastasiya-Romanova 秀
@ Anastasiya-Romanova 秀 Assez juste :)
plannapus
Des points bonus pour avoir fà la fois le nom de la fonction et l'un de ses arguments :)
JDL
4

Octave, 85 octets MATLAB, 123, 114, 105, 94 octets

Décidé de traduire cela en Octace, de tirer parti de l'indexation directe et des capacités incrémentielles. Prend l'entrée sur le formulaire:, f(a,operator)a = [number1, number2], operator==1donne le produit et operator==2donne la somme.

function[x,i]=f(a,o)
g={@prod,@sum}{o};x=g(a);i=1;while(x=g(num2str(x)-48))>9;i++;end

Explications:

g={@prod,@sum}{o} : Choisit la fonction, le produit ou la somme appropriés et les affecte à g

x=g(a) prend la somme ou le produit des intrants

i=1; ... i++ : Incrementer pour compter le nombre d'étapes

while(x=g(num2str(x)-48))>9;
          num2str(x)-48)     % turns a number 123 into an array [1 2 3].
        g(num2str(x)-48))    % Takes the sum or product of the array
      x=g(num2str(x)-48))    % Assign that value to the variable x
      x=g(num2str(x)-48))>9  % Checks if x > 9, continue looping if yes

Suppression de deux nouvelles lignes, d'un espace, et placement des deux nombres entrés dans un vecteur au lieu d'arguments séparés. Cela a sauvé 9 octets, grâce à pajonk! Supprimé k=@(x)...pour sauver encore 11 octets grâce à beaker =) Enfin, traduit le tout en Octave pour sauver encore 9 octets ...

Stewie Griffin
la source
4

Java, 164 159 146 octets

int[]p(int t,int m,String[]d){int r=m;for(String i:d){int x=Integer.decode(i);r=m<1?r+x:r*x;}return r>9?p(++t,m,(r+"").split("")):new int[]{r,t};}

Le premier argument est juste le compteur, toujours 0

Le second argument est la méthode, 0 pour ADD et 1 pour MULTIPLY.

Le troisième argument est un tableau de chaînes, qui contient les valeurs à ajouter / multiplier.

Ungolfed

public static int[] p(int t, int m, String[] d) {
    int r = m;
    for (String i : d) {
        int x = Integer.decode(i);
        r = m < 1 ? r + x : r * x;
    }
    return (r + "").length() > 1 ? p(++t, m, (r + "").split("")) : new int[]{r, t};
}

merci à @Kevin Cruijssen d'avoir coupé quelques octets.

merci à @milk pour avoir rasé 5 octets.

Programme de test

public static final int ADD = 0;
public static final int MULTIPLY = 1;

public static void main(String[] args) {
    System.out.println(Arrays.toString(p(0, ADD, new String[]{"12", "123"}))); //9
    System.out.println(Arrays.toString(p(0, MULTIPLY, new String[]{"12", "123"}))); //6
}

public static int[] p(int t, int m, String[] d) {
    int r = m;
    for (String i : d) {
        int x = Integer.decode(i);
        r = m < 1 ? r + x : r * x;
    }
    return (r + "").length() > 1 ? p(++t, m, (r + "").split("")) : new int[]{r, t};
}
Shaun Wild
la source
Bien, plus court que ma réponse Java . Cependant, vous êtes également censé imprimer les étapes et la réponse qui manque actuellement à votre réponse.
Kevin Cruijssen
@ KevinCruijssen Ahh. C'est ennuyeux .. Je vais essayer de résoudre ce problème maintenant.
Shaun Wild
Btw, vous pouvez jouer au golf votre réponse actuelle un peu. m==0peut être m<1et Integer.parseIntpeut être Integer.decode.
Kevin Cruijssen
Je n'utilise pas beaucoup Java, mais avez-vous besoin de cette jvariable à la fin? Deux (r+"")fois en ligne, on dirait que cela raserait quelques octets.
lait
1
Ne pouvons-nous pas changer mes publications à l'avenir? Si vous souhaitez suggérer une modification, faites-le dans les commentaires.
Shaun Wild
3

Gelée , 17 octets

+×⁵?µDSP⁵?$ÐĿµL;Ṫ

Essayez-le en ligne!

Avec des arguments comme x y 1, ceci calcule la somme d'Anastasiya x (+) y.

Avec des arguments comme x y 0, ceci calcule le produit Anastasiya x (*) y.

La sortie est donnée comme [number of steps, result].

Lynn
la source
Merci pour la réponse, mais la sortie de votre programme ne contient pas le nombre d'étapes requis. Est-ce que j'ai râté quelque chose?
Commentaires
3

Python, 160 146 129 octets

def r(s):
 n=str(eval(s));c=0
 while n[1:]:exec("n=str(reduce(lambda a,b:a%sb,map(int,list(n))))"%"*+"["+"in s]);c+=1
 return n,c

Publierai une explication bientôt.

La saisie est sous la forme 12+12ou 5*35(avec normale +et *signes), et suppose que ce sont les deux seuls opérateurs.

Il peut gérer des entrées numériques aussi importantes que la mémoire de votre ordinateur le permet.

Je suis presque certainement convaincu que cela peut être plus loin.

EDIT: 16 31 octets enregistrés grâce à @Copper.

clismique
la source
Merci pour la réponse, (+1). Peut-il gérer des entrées de grand nombre?
Commentaires
@ Anastasiya-Romanova 秀 Uhmmm ... Je suis à peu près sûr qu'ils le peuvent. Pouvez-vous me donner des exemples de grandes entrées? Je vais essayer de calculer à partir de ceux-ci.
Clismique
Peut-être: 3218753647208435810122106 * 29349566754?
Commentaires
1
@ Anastasiya-Romanova 秀 Oui, cela a fonctionné en environ 0,5 seconde, mais cela n'a pas été chronométré correctement.
Clismique
Vous pouvez passer "+" if "+" in s else "*"à "*+"["+"in s], puis au lieu de l’affecter à t, ajoutez-le simplement dans l’ execappel.
Cuivre
3

R, 110 octets

Utilisation du séparateur de @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)}

f=function(A,F,B){
  r=Reduce                                  # Shortcut for Reduce
  x=r(F,A,B)                                # A operator B
  y=1                                       # Initiate counter
  while(x>9)                                # If number of digits > 2, or number > 9
  {m=nchar(x)                               # Count number of digits
    x=r(F,x%%10^(1:m)%/%10^(1:m-1))         # @plannapus's splitter, then feed into the A operator B operator C, etc while condition true
    y=y+1}                                  # Increment counter
  cat(x,y)}                                 # Print

Sortie

> f(136,"*",2356)
0 2
> f(31,"+",81)
4 2
> f(2,"+",3)
5 1
> (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)})(21,"*",111)
8 3

edit: je ne peux pas compter.

Vlo
la source
R est fantastique parce que cela nous permet de raccourcir sa fonction, ce qui est précieux pour le golf. (+1)
Anastasiya-Romanova
3

Clojure 126 octets

(defn f [o a b] (loop [n (o a b) c 1] (if (< n 10) [n c] (recur (reduce #(o %1 %2) (map #(- (int %) 48) (str n))) (inc c)))))

La fonction s'appelle comme suit:

(f + 81 31)

Voici le code ungolfed:

(defn f [o a b]
  (loop [n (o a b) c 1]
    (if (< n 10)
      [n c]
      (recur (reduce #(o %1 %2)
                     (map #(- (int %) 48) (str n)))
             (inc c)))))

(def test-cases [[+ 81 31]
                 [+ 351 14568]
                 [* 21 111]
                 [* 136 2356]])

(map #(apply f %) test-cases)
;;=> ([4 2] [6 3] [8 3] [0 2])

N'oubliez pas que Clojure est encore nouveau pour moi, ce n'est donc probablement pas la meilleure solution. Le défi était amusant tout de même. De plus, le code a fonctionné avec de très grands nombres sans aucune difficulté.

James B.
la source
C'est très tard, mais vous pouvez réduire la plupart des espaces.
Clismique
2

Perl 6 53 octets

{$/=(&^b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

Puisque ( 12, &[+], 123 )est acceptable pour l'entrée, je peux le réduire à 53 octets.
( &[+]est l'abréviation de &infix:<+>"révérence" à l'opérateur d'addition infixe numérique)

Si le deuxième argument devait être une chaîne, (+)ce serait 87 octets.

{my&b=::("&infix:<$^b.substr(1,1)>");$/=(b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

Explication:

# bare block lambda with 3 parameters declared using placeholder syntax
{
  # store list into 「$/」
  # ( used 「$/」 so that I don't have to declare a variable )
  $/ = (

    # declare second placeholder parameter, and call it
    &^b(
      # with the first and third placeholder parameters
      $^a, $^c
    ),

    # bare block lambda with implicit parameter 「$_」
    {
      # list reduce using the second parameter from outer block
      [[&b]]

      # a list of the digits of 「$_」 (implicit method call)
      .comb
    }

    # keep doing that until
    ...

    # it produces something smaller than 10
    # ( Whatever lambda )
    10 > *
  );

  # returns

  # final result ( last value from list )
  $/[ * - 1 ],
  # and count of values in list
  +$/
}

Tester:

#! /usr/bin/env perl6
use v6.c;
use Test;

my &anastasiya-math = {$/=(&^b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

my @test = (
  (  81, &[+], 31    ) => (4, 2),
  ( 351, &[+], 14568 ) => (6, 3),
  (  21, &[*], 111   ) => (8, 3),
  ( 136, &[*], 2356  ) => (0, 2),
);

plan +@test;

for @test -> $_ ( :key(@input), :value(@expected) ) {
  cmp-ok anastasiya-math(|@input), &[»==«], @expected;
}

Utilisation normale:

# override built-in Bag operator 「(+)」 in current lexical scope
my &infix:<(+)> = &anastasiya-math.assuming: *, &[+], *;

# add a new operator
my &infix:<(*)> = &anastasiya-math.assuming: *, &[*], *;

say 12 (+) 123; # (9 2)
say 12 (*) 123; # (6 5)
Brad Gilbert b2gills
la source
2

Python 2, 107 97 octets

g=lambda x,o,i=1:x<10and[x,i]or g(eval(o.join(`x`)),o,i+1)
lambda a,o,b:g(eval('%s'*3%(a,o,b)),o)

Une fonction anonyme qui prend en entrée via l'argument d'un premier opérande a, un opérateur o( '+'ou '*') et un deuxième opérande b, et renvoie une liste du formulaire [result, steps].

Comment ça marche

La fonction anonyme crée une chaîne en concaténant les opérandes avec l'opérateur entre eux, puis l'évalue. c'est la première étape décrite dans la question. Ensuite, cette valeur et l'opérateur sont passés à la fonction récursive g. Ici, un compteur i, qui est incrémenté pour chaque appel récursif, est utilisé. Si l'entrée est inférieure à 10, un seul chiffre doit avoir été atteint, c'est donc cela qui iest retourné. Sinon, l'entrée est convertie en chaîne et chaque caractère de cette chaîne est joint à l'opérateur, ce qui donne le calcul souhaité, qui est ensuite évalué et passé à la fonction de manière récursive.

Essayez sur Ideone

TheBikingViking
la source
(+1) en attendant l'explication :)
Anastasiya-Romanova 秀
2

Groovy, 102 octets

def p,e,r;p={t,m,d->e=d*.toInteger();r=m<1?e.sum():e.inject{a,b->a*b};r>9?p(++t,m,""+r as List):[r,t]}

Degolfed

def p,e,r
p = { t, m, d ->
    e = d*.toInteger()
    r = (
            m<1
                ? e.sum()
                : e.inject { a, b -> a * b }
        )
    r > 9
        ? p(++t, m, "" + r as List)
        : [r,t]
}

Explication

Basé sur l'excellente solution de @Sean Bean pour Java.

  • p: La fermeture (fonction, lambda, peu importe) qui implémente la solution
  • t: La profondeur de l'appel en cours (nombre d'itérations) pdoit toujours être invoquée avect=1
  • m: Opération à effectuer 0pour "ajouter", 1pour "multiplier"
  • d: La liste des opérandes, chaque opérande est un objet String
  • e: Les éléments de d, chacun converti en un entier
  • r: La somme ou le produit de e, en fonction de l'opérationm
  • déclaration de résultat, commençant par r > 9:
    • Si plusieurs chiffres ( r > 9), réinvoquez, incrémentez la profondeur tet convertissez-les ren une liste de chaînes de chiffres (et renvoyez le résultat).
    • Si un seul chiffre, retour ret tsous forme de liste.

Programme de test

final ADD = 0
final MULTIPLY = 1
println p(1, ADD, ["12", "123"]) //9, 2
println p(1, MULTIPLY, ["12", "123"]) //6, 5
println p(1, ADD, ["2", "3"]) //5, 1

Résultats

[9, 2]
[6, 5]
[5, 1]
Roger Glover
la source
2

Haskell, 76 70 octets

 (x#y)f=until(<[10])(\[s,i]->[foldr(f.read.pure)0$show s,i+1])[f x y,1]

Retourne une liste de deux éléments avec le résultat et le nombre d'étapes. Fonctionne pour les grands nombres arbitraires. Exemple d'utilisation: (351#14568)(+)-> [6,3].

Edit: Merci à @BlackCap pour 6 octets.

nimi
la source
Vous pouvez remplacer (-48+).fromEnumparread.pure
BlackCap
2

R, 91 octets

En utilisant le code de @ Vlo, qui utilise le séparateur de @ plannapus, et quelques idées générées en jouant au golf, la réponse de Frédéric est la réponse la plus courte à ce jour. (Un nombre inhabituellement élevé de réponses R ici aujourd'hui ...)

function(A,F,B){x=F(A,B);while(x>9){m=nchar(x);x=F(x%%10^(1:m)%/%10^(1:m-1));T=T+1};c(x,T)}

De manière cruciale, cela nécessite que la saisie de l'opérateur soit sumpour (+) ou prodpour (*). Selon les règles du défi, cela semble aller.

Avec indentation:

function(A,F,B){
  x=F(A,B);
  while(x>9){
    m=nchar(x);
    x=F(x%%10^(1:m)%/%10^(1:m-1));
    T=T+1
  };
  c(x,T)
}

Les principales différences avec la réponse de @ Vlo sont les suivantes:

  1. Au lieu d'utiliser Reduce, nous nous appuyons sur l'argument d'entrée en tant que fonction et nous l'appelons simplement explicitement. (Oui pour les fonctions étant des objets de première classe!)
  2. Au lieu d'initialiser une nouvelle variable en tant que compteur, nous abusons des fonctions intégrées de R et de son utilisation T, qui est évaluée à TRUE(aka 1), mais puisque ce n'est pas une variable réservée, nous pouvons la modifier. Ainsi T+Test 2. Nous utilisons donc cela comme notre compteur.
  3. Au lieu d’ catinverser la sortie, nous la renvoyons simplement sous forme de vecteur avec c. En plus d'économiser deux octets, le fait que la sortie soit forcée dans un vecteur garantit sa Tclasse numeric. Si nous utilisons catet Tn’avons pas été incrémentés, nous obtenons une sortie erronée du type 1 TRUE.
tourbull
la source
vous pouvez restructurer la whileboucle comme suit, en changeant Fd'être quelque chose d' autre pour éviter les conflits de nom: 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)}}. C'est incroyable le nombre de figures de golf que nous avons proposées ces dernières années :)
Giuseppe
@Giuseppe Nice restructuration! Je ne trouve pas le méta-consensus pour le moment, mais je suis raisonnablement convaincu que l'utilisation de la astuce Tet du Fcompteur dans une fonction est en réalité invalide, car cela signifie que la fonction ne peut être appelée qu'une seule fois. Donc, cette réponse (et plusieurs de mes autres!) Ne sont pas valides, à moins d'indication explicite rm(T)à la fin. Je vais continuer à chercher ce méta-post afin de pouvoir être sûr de ne pas l'avoir rêvé.
rturnbull
Je crois que le truc Tet Fastuce est parfaitement valable tant que vous ne modifiez pas Tou Fdans l'environnement global. par exemple, f=function(){T=T+1;T}revient systématiquement 2. Je pense que ceci est le meta post auquel vous faites référence.
Giuseppe
@ Giuseppe Ah oui, vous avez raison sur les deux points. Merci!
rturnbull
1

Ruby, 55 octets

Appel récursif. Très différent de la réponse JavaScript de @ edc65, mais comme je l’optimisais, il est finalement devenu un port direct développé presque indépendamment de leur réponse, moins une optimisation finale consistant à vérifier le résultat évalué à la place de la longueur de la liste des opérandes passées. , ce qui m'a permis de dépasser leur nombre d'octets.

L'entrée est une chaîne représentant l'opérateur et un tableau contenant les opérandes.

Essayez-le en ligne.

f=->o,x,i=1{y=eval x*o;y>9?f[o,y.to_s.chars,i+1]:[y,i]}
Valeur d'encre
la source
Le résultat est correct, mais le nombre d'étapes requis pour obtenir une valeur à un chiffre est incorrect. Pourriez-vous rectifier votre code?
Anastasiya-Romanova 秀
@ Anastasiya-Romanova 秀 ah, tu as raison. Mon ancienne logique demandait de commencer i=0et j'ai en quelque sorte oublié de refactoriser.
Valeur d'encre
1

Perl, 38 octets

Comprend +2 pour -ap

Exécutez avec l'entrée sur STDIN et les espaces autour de l'opérateur:

amath.pl <<< "12 + 123"
amath.pl <<< "12 * 123"

La sortie est un chiffre et les étapes séparées par +A

amath.pl:

#!/usr/bin/perl -ap
1while++$\,$_=eval."+A",s/\B/$F[1]/g

Si la sortie des étapes dans unary est correcte, cette version de 35 octets fonctionne mieux:

#!/usr/bin/perl -lap
1while$\.=1,$_=eval,s/\B/$F[1]/g
Ton Hospel
la source
1

Mathematica, 105 94 octets

Code.

{x,y}=(c=0;f//.a_:>(c++;t=o@@IntegerDigits@a);{t,c})&/.{{f->#1+#2,o->Plus},{f->#1#2,o->Times}}

Usage.

x[81, 31]
(* {4, 2} *)

x[351, 14568]
(* {6, 3} *)

y[21, 111]
(* {8, 3} *)

y[136, 2356]
(* {0, 2} *)

Explication.

Les deux fonctions x(pour (+)) et y(pour (*)) sont créées en même temps en remplaçant les paramètres fet oen

(c = 0;
 f //. a_ :> (c++; t = o@@ IntegerDigits@a);
 {t, c}
)&

avec leurs valeurs appropriées. Pour x, fdevient #1 + #2et odevient Plus; car y, respectivement ils deviennent #1 #2et Times. Réécriture de la fonction xpour la dernière partie de l'explication:

x = (
  c = 0;
  #1 + #2 //. a_ :> (c++; t = Plus@@IntegerDigits@a); 
  {t, c}
) &;

(* The symbol //. stands for ReplaceRepeated. 
   The rule a_ :> (c++; t = Plus@@IntegerDigits@a) is applied until the result no longer 
changed. Specifically, the rule increments the counter of 1 at each step (this is c++), 
then takes the sum of the digits of the previous result (this is Plus@@IntegerDigits@a). 
The rule stops to apply when the variable t is less than 10. We return the final result and 
the number of steps with {t, c}. *)

la source
1

Java 7, 203 195 192 octets

int c=1;String c(long a,long b,int o){return p(((o<1?a+b:a*b)+"",o)+","+c;}long p(String n,int o){long x=o,q;for(String s:n.split("")){q=new Long(s);x=o<1?x+q:x*q}c++;return x<10?x:p(x+"",o);}

Il utilise long(valeur maximale de 2 63 -1). S'il utilisait à la intplace (valeur maximale de 2 31 -1), il ne contiendrait qu'un octet en moins ( 191 octets ):

int c=1;String c(int a,int b,int o){return p(((o<1?a+b:a*b)+"",o)+","+c;}int p(String n,int o){int x=o,q;for(String s:n.split("")){q=new Integer(s);x=o<1?x+q:x*q}c++;return x<10?x:p(x+"",o);}

Il peut probablement être joué un peu plus au golf. Avoir à imprimer les étapes ainsi que la réponse pour les deux opérateurs prend cependant quelques octets.
Utilise 0 (pour (+)) et 1 (pour (*)).

Ungolfed & code de test:

Essayez ici.

class Main{
  static int c = 1;
  static String c(long a, long b, int o){
    return p((o < 1 ? a+b : a*b) + "", o) + "," + c;
  }

  static long p(String n, int o){
    long x = o,
         q;
    for(String s : n.split("")){
      q = new Long(s);
      x = o < 1
           ? x + q
           : x * q;
    }
    c++;
    return x < 10
            ? x
            : p(x+"", o);
  }

  public static void main(String[] a){
    System.out.println(c(81, 31, true));
    c = 1;
    System.out.println(c(351, 14568, true));
    c = 1;
    System.out.println(c(21, 111, false));
    c = 1;
    System.out.println(c(136, 2356, false));
  }
}

Sortie:

4,2
6,3
8,3
0,2
Kevin Cruijssen
la source