Pliez l'entier pour économiser de l'espace!


20

Le mathématicien fou possède une vaste collection de nombres, et donc l'espace qu'il a laissé est assez limité. Pour en sauver, il doit plier ses entiers, mais malheureusement il est vraiment paresseux. Votre tâche, si vous souhaitez l'aider, est de créer une fonction / programme qui plie un entier positif donné pour notre maniaque des nombres.

Comment plier un entier?

S'il est divisible par la somme de ses chiffres, divisez-le par la somme de ses chiffres. S'il ne répond pas à cette exigence, prenez son reste lorsqu'il est divisé par la somme de ses chiffres. Répétez le processus jusqu'à ce que le résultat atteigne 1. L'entier replié est le nombre d'opérations que vous avez dû effectuer. Prenons un exemple (disons 1782):

  1. Obtenez la somme de ses chiffres: 1 + 7 + 8 + 2 = 18. 1782est divisible par 18, donc le nombre suivant est 1782 / 18 = 99.

  2. 99n'est pas divisibles par 9 + 9 = 18, d' où nous prenons le reste: 99 % 18 = 9.

  3. 9est évidemment divisible par 9, donc nous le divisons et obtenons 1.

Le résultat est 3, car 3 opérations ont été nécessaires pour atteindre 1.

Règles et spécifications

  • Certains nombres entiers peuvent avoir la somme de chiffres égaux à 1, tels que 10ou 100. Votre programme n'a pas besoin de gérer de tels cas. Cela signifie que vous serez assuré que l'entier donné en entrée n'a pas la somme des chiffres égale à 1, et qu'aucune opération avec l'entier donné ne donnera un nombre dont la somme des chiffres est 1(sauf pour 1lui-même, qui est le " cible"). Par exemple, vous ne recevrez jamais 10ou 20en entrée.

  • L'entrée sera un entier positif supérieur à 1.

  • Les échappatoires par défaut s'appliquent.

  • Vous pouvez prendre des entrées et fournir des sorties par n'importe quel moyen standard .


Cas de test

Entrée -> Sortie

2 -> 1
5 -> 1
9 -> 1
18 -> 2
72 -> 2
152790 -> 2
152 -> 3
666 -> 3
777 -> 3
2010 -> 3
898786854 -> 4

Voici un programme qui vous permet de visualiser le processus et d'essayer plus de cas de test.


C'est le , donc le code le plus court dans chaque langue (marqué en octets) gagne!


Inspiré par ce défi , même s'il peut ne pas sembler lié au premier abord.
M. Xcoder

3
Cela fonctionnera comme une solution provisoire, mais à long terme, le mathématicien devrait vraiment envisager d'acheter l'un des hôtels Hilbert . Vous pouvez toujours trouver une pièce inutilisée dans l'un d'eux.
Ray

alors que 8987868546c'est une entrée valide, cela cassera votre outil de test, et aussi beaucoup (sinon toutes) des réponses ...
Mischa

@MischaBehrend Votre exemple n'est pas une entrée valide. Je pense que vous avez mal interprété mon dernier cas de test. L'entrée valide était 898786854, non 8987868546(vous avez ajouté un 6à la fin)
M. Xcoder

nvm ... devrait lire toute la première règle ... en laissant ceci ici afin que vous sachiez pourquoi je pensais que c'était valide: ce n'était pas une erreur ... je l'ai changé intentionnellement pour tester ces scripts ... et en lisant les règles, il est une entrée valide. La somme de tous les chiffres 8987868546 n'est pas 1 ( règle 1 respectée ) et 8987868546est un entier positif supérieur à 1 ( règle 2 respectée ).
Mischa

Réponses:


6

05AB1E , 13 12 octets

[¼DSO‰0Kθ©#®

Essayez-le en ligne!

Explication

[               # start loop
 ¼              # increment counter
  D             # duplicate current value
   SO           # sum the digits in the copy
     ‰          # divmod the current value by its digit-sum
      0K        # remove 0 from the resulting list
        θ       # pop the last element
         ©      # store a copy in register
          #     # if the current value is 1, break
           ®    # push the copy from register
                # implicitly output counter

6

Python 2 , 63 57 octets

-1 grâce à totalementhumain
-1 grâce à M. Xcoder
-4 grâce à reffu

def f(n):a=sum(map(int,`n`));return n>1and-~f(n%a or n/a)

Essayez-le en ligne!




1
57 octets Je m'excuse également d'avoir fait de ma réponse ma première réponse. Cela a plus de sens en tant que commentaire
reffu

5

Haskell, 85 78 octets

f 1=0
f n|r<1=1+f(n`div`s)|1<2=1+f r where s=sum(read.pure<$>show n);r=n`rem`s

Enregistré 7 octets grâce à Bruce Forte.

Essayez-le en ligne.


Économisez encore plus d'octets en utilisant divModet en supprimant where: Essayez-le en ligne!
Laikoni

@Laikoni Wow, c'est tout à fait une amélioration! Veuillez le poster comme une réponse différente; il est assez différent du mien. BTW: Je cherchais une astuce pour me débarrasser du where. Je vais l'utiliser à l'avenir. :)
Cristian Lupascu

sum[read[d]|d<-show n]enregistre un octet
nimi

5

JavaScript (ES6), 66 58 51 49 octets

Prend l'entrée comme un entier. Renvoie falsepour 0ou 1et renvoie une erreur de débordement lorsqu'il rencontre un nombre dont les chiffres s'additionnent 1.

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1
  • 8 octets enregistrés avec l'aide de Justin .

Essaye-le

o.innerText=(

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1

)(i.value=898786854);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>


1
Pourriez-vous enregistrer quelques octets en additionnant les chiffres à l'aide de eval(array.join`+`)?
Justin Mariner

Je pourrais en effet, @JustinMariner - vous m'avez ninjaed à elle! Merci :)
Shaggy

4

Husk , 12 octets

←€1¡Ṡ§|÷%oΣd

Essayez-le en ligne!

Explication

←€1¡Ṡ§|÷%oΣd  Implicit input, e.g. n=1782
    Ṡ§|÷%oΣd  This part defines the transformation.
         oΣ   Sum of
           d  digits: s=18
    Ṡ   %     n mod s: 0
     §|       or (take this branch if last result was 0)
       ÷      n divided by s: 99
   ¡          Iterate the transformation: [1782,99,9,1,1,1,...
 €1           Index of 1 (1-based): 4
←             Decrement: 3
              Print implicitly.



2

Rétine , 100 octets

$
;
{`(.+);
$1$*1;$&
(?<=;.*)\d(?=.*;)
$*
.*;1;(.*)
$.1
r`(1)*(\3)*;(1+);
$#1;$#2;1
0;(.*);|;.*;
$1;

Essayez-le en ligne! Link ne comprend que des cas de test plus petits car les plus grands prennent trop de temps.


2

Mathematica, 73 octets

(t=#;For[r=0,t>1,r++,If[(s=Mod[t,g=Tr@IntegerDigits@t])<1,t=t/g,t=s]];r)&

Peut ==0être remplacé par <1?
M. Xcoder

@ Mr.Xcoder oui, bien sûr! J'ai fait une version trieuse ...
J42161217

2

PHP, 68 + 1 octets

sortie unaire:

for($n=$argn;$n>1;$n=$n%($s=array_sum(str_split($n)))?:$n/$s)echo 1;

sortie décimale, 73 + 1 octets:

for($n=$argn;$n>1;$i++)$n=$n%($s=array_sum(str_split($n)))?:$n/$s;echo$i;

Exécuter en tant que pipe avec -nRou l' essayer en ligne .


L'opérateur Elvis nécessite PHP 5.3 ou une version ultérieure. Pour les anciens PHP, remplacez ?:par ?$n%$s:(+5 octets).


2

Rubis, 46 octets

f=->n{s=n.digits.sum;n<2?0:1+f[n%s<1?n/s:n%s]}

2

Haskell , 94 93 89 88 octets

Cela semble vraiment long ..

length.fst.span(/=1).iterate g
g x|(d,m)<-x`divMod`sum[read[d]|d<-show x]=last$m:[d|m<1]

Essayez-le en ligne!

Merci @Laikoni & @nimi pour avoir joué 1 octet chacun!





1

Perl, 71 octets, 64 octets, 63 octets

-pl

$c=0;while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c};$_=$c

Essayez-le en ligne

EDIT: enregistré 7 octets, grâce au commentaire de Xcali

-p

while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

EDIT: depuis 5.14 substitution non destructive s /// r

-pl

while($_>1){$s=eval s/\B/+/gr;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

Est le -pl le dessus est censé être un drapeau de ligne de commande à la place?
Erik the Outgolfer

oui ce sont des options perl
Nahuel Fouilleul

Vous devriez compter le -pldrapeau selon ce post .
Erik the Outgolfer

J'ai compté 69 octets +2 pour les options pl, est-ce correct?
Nahuel Fouilleul

Vous pouvez jouer au golf un peu plus bas. $cn'a pas besoin d'être initialisé. Il commencera à undefce qui est 0. Le point-virgule après la fermeture while peut aller. De plus, vous n'en avez pas besoin -l. Il n'est pas nécessaire de prendre plusieurs entrées en une seule fois.
Xcali

1

Dyalog APL, 36 octets

{x←+/⍎¨⍕⍵⋄1=⍵:00=x|⍵:1+∇⍵÷x1+∇x|⍵}

Essayez-le en ligne!

Comment?

{
   x←+/⍎¨⍕⍵       x = digit sum
   1=⍵:0          if arg = 1: bye
   0=x|⍵:1+∇⍵÷x   if arg divisible by x: recurse with arg/x
   1+∇x|⍵         recurse with arg mod x
}

1

Gaia , 13 octets

-@{:ΣZ¤∨)‡}°\

Essayez-le en ligne!

Explication

-              Push -1 (this will be the counter)
 @             Push input (the starting number)
  {:ΣZ¤∨)‡}°   Repeat this block until the results of 2 consecutive runs are the same:
   :            Copy the number
    Σ           Digital sum
     Z          Divmod number by digital sum
      ¤         Swap
       ∨        Logical or: left-most non-zero out of (number mod sum, number div sum)
        )‡      Increment the counter
            \  Delete the final 1, implicitly print the counter

1

Matlab, 150 octets

function[d]=X(x) 
d=0;while ~strcmp(x,'1')z='sum(str2num(x(:)))';a=eval(['rem(',x,',',z,')']);y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));x=y;d=d+1;end

Les entrées doivent être données à la fonction sous la forme d'une chaîne, telle que X ('152').

La fonction fonctionne en bouclant et en incrémentant d. lex=y; ligne était nécessaire pour éviter une erreur de Matlab essayant de lire et d'écraser une valeur de variable en même temps, apparemment, ce qui était nouveau pour moi.

Non golfé:

function[d]=X(x) 
d=0;
while ~strcmp(x,'1')
    z='sum(str2num(x(:)))';
    a=eval(['rem(',x,',',z,')']);
    y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));
    x=y;
    d=d+1;
end


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.