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!

M. Xcoder
la source
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
Emigna
la source
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!

Arfie
la source
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.

Cristian Lupascu
la source
É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>

Hirsute
la source
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.
Zgarb
la source
3

C # (.NET Core) , 87 octets

n=>{int i=0,k,l;for(;n>1;++i){for(l=n,k=0;l>0;l/=10)k+=l%10;n=n%k>0?n%k:n/k;}return i;}

Essayez-le en ligne!

Fonction lambda qui prend et retourne un entier.

jkelm
la source
3

Japt , 22 19 17 octets

-3 octets grâce à @Shaggy.
-2 octets grâce à @ETHproductions


ìx
>1©1+ßU%VªU/V

Essayez-le en ligne!

Justin Mariner
la source
1
<s> 20 octets </s> 19 octets
Shaggy
1
En fait, vous pouvez changer s_¬pour ìenregistrer encore deux octets :-)
ETHproductions
@ETHproductions Oh, c'est vraiment cool, merci!
Justin Mariner
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.

Neil
la source
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)&
J42161217
la source
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).

Titus
la source
2

Rubis, 46 octets

f=->n{s=n.digits.sum;n<2?0:1+f[n%s<1?n/s:n%s]}
m-chrzan
la source
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!

ბიმო
la source
1

Gelée , 12 octets

dDS$Ṛȯ/µÐĿL’

Essayez-le en ligne!

Erik le Outgolfer
la source
Approche intéressante! Maintenant, nous attendons Jonathan: P
M. Xcoder
@ Mr.Xcoder Je ne pense pas cette fois :)
Erik the Outgolfer
Moi non plus, c'était une blague :)
M. Xcoder
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
Nahuel Fouilleul
la source
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
}
Uriel
la source
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
Chat d'affaires
la source
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
sintax
la source