Pandigital Doubling


14

Inspiré par ce CMC

Étant donné un entier positif supérieur à 0, effectuez l'opération suivante:

  • Si les dix chiffres simples ( 1234567890) sont dans le nombre au moins une fois, sortez le compte et quittez le programme
  • Sinon, doublez le nombre et répétez, en augmentant le nombre.

Le décompte commence à 0 et correspond au nombre de fois où l'entrée a été doublée. Par exemple, si l'entrée était 617283945, elle devrait être doublée une fois car 1234567890 contient les 10 chiffres.

C'est un donc le code le plus court l'emporte. L'entrée peut être considérée comme une chaîne, si vous le souhaitez.

Cas de test

input => output

617283945 => 1
2 => 67
66833 => 44
1234567890 => 0
100 => 51
42 => 55

Pouvons-nous prendre l'entrée comme une chaîne?
Stephen

@Stephen vous pouvez prendre l'entrée comme une chaîne.
caird coinheringaahing

3
Est-il garanti que pour certains, nil en existe de ktels qui nksont pandigital? J'adorerais voir une preuve.
shooqie

1
@bfontaine Chat Mini Challenge
caird coinheringaahing

3
@shooqie Proof! Pour tout n qui est coprime à 10, c'est aussi coprime à 10 ^ 10, et donc il existe des k tels que nk est 1 mod 10 ^ 10. Puis 1234567890 * nk = 1234567890 mod 10 ^ 10, donc chaque chiffre apparaît nécessairement au moins une fois. Sinon, multipliez par 2, 5 ou 25 si nécessaire pour que le dernier coprime à chiffres non nuls avec 10, et une variante des preuves ci-dessus fonctionne (officiellement, n = 10 ^ m * p, où p satisfait à la condition ci-dessus , alors 1234567890 * p * k comme ci-dessus est pandigital, donc 1234567890 * p * k * 10 ^ m = 1234567890 * k * n est). :)
B. Mehta

Réponses:



4

J , 24 23 octets

(]1&(+$:)2**)10>#@~.@":

Essayez-le en ligne!

Explication

(]1&(+$:)2**)10>#@~.@":  Input: integer n
                     ":  Format as string
                  ~.@    Unique
                #@       Length
             10>         Less than 10
           *             Multiply, gives n if previous was true, else 0
         2*              Multiply by 2
 ]                       Get the previous condition
  1&(   )                Execute this if true on 2n, else return 0
      $:                   Recurse
  1  +                     Add 1

Agréable. J'étais bloqué sur la collecte des résultats, je n'ai pas pensé à utiliser ce type de fonction récursive.
Conor O'Brien

4

05AB1E , 11 10 octets

-1 octet grâce à scottinet

[D9ÝåË#·]N

Essayez-le en ligne! ou comme suite de tests

[          // Start infinity loop
 D         // Duplicate current value (or input)
  9Ý       // Push [0,1,2,3,4,5,6,7,8,9]
    å      // Does each exist in the current value
     Ë#    // Break if all equal (if every digit exists)
       ·   // Else double the current value
        ]N // End loop and print the number of times through the loop


@scottinet Merci! Je ne sais pas comment j'ai raté ça.
Riley

@riley allait dire use xmais c'est 10 aussi ... Belle réponse. La pensée xs'en débarrasserait D, mais c'est la même idée.
Urne de poulpe magique du

3

Perl 6 ,31 28 octets (27 caractères)

-3 octets grâce à @Joshua

{($_,2×*...*.comb.Set>9)-1}

Essayez-le en ligne!

Explication: Toujours la même construction pour générer de manière récursive des listes. Le premier élément est le nombre donné ( $_), chaque élément suivant est 2 fois le précédent ( 2×*- nous utilisons ×, car, bien que le caractère à 2 octets, c'est toujours 1 octet moins cher que 2 * *), et nous le faisons jusqu'à ce que la condition de fin de *.comb.unique>9soit remplie , c'est-à-dire lorsqu'il y a plus de 9 caractères uniques dans le nombre. (Techniquement, nous décomposons la chaîne en une liste de caractères avec .comb, la forçons à un ensemble avec .Set(bien sûr, les ensembles ne contiennent chaque élément qu'une seule fois) et comparons avec 9, ce qui force l'ensemble dans un contexte numérique, ce qui donne à son tour son nombre d'éléments.)

Enfin, nous soustrayons 1 de cette liste. Encore une fois, la liste est forcée dans un contexte numérique, donc ce que nous retournons est 1 de moins que la longueur de cette liste.


Vous pouvez utiliser .Setau lieu de .uniquepour enregistrer 3 octets.
Joshua

@Joshua, bon point! Je vous remercie. Je n'ai jamais pensé à cela.
Ramillies

3

JavaScript (ES6) + big.js , 84 74 73 70 octets

Merci @ ConorO'Brien d' avoir économisé 10 octets en suggérant big.js au lieu de bignumber.js
Merci à @Rick Hitchcock pour -1 octet
Merci à @Shaggy pour -3 octets

f=n=>[..."4"+2**29].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2))

Prend l'entrée comme chaîne; prend en charge jusqu'à environ 2 69 en raison de la conversion automatique de la notation scientifique se produisant au-delà de ce point.

Extrait de test

f=n=>[..."4"+2**29].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2))

;[617283945, 2, 66833, 1234567890, 100, 42].forEach(t=>console.log(`f(${t}) = `+f(t)))
<script src="https://cdn.rawgit.com/MikeMcl/big.js/c6fadd08/big.min.js"></script>

Plage infinie, 106 88 87 84 octets

En utilisant l'option config pour désactiver efficacement la notation scientifique lors de la conversion de nombres en chaînes, nous pouvons avoir une plage presque infinie.


Peut-être pourriez-vous raccourcir le BigNumberbit en utilisant big.js ?
Conor O'Brien

@ ConorO'Brien Cela va certainement aider, surtout parce qu'il newest facultatif dans celui-ci. Mettra à jour, merci!
Justin Mariner

Économisez un octet avec f=n=>[..."0123456789"].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2)).
Rick Hitchcock

Nous n'avons pas besoin de gérer les grands entiers afin que vous puissiez supprimer big.js si vous le souhaitez, ce qui vous ramène à 61 octets. Et vous pouvez économiser 3 octets en remplaçant la chaîne de chiffres par "4"+2**29: tio.run/##BcGxDkAwEADQb2GQO41LNBZDbX7AKgbhKkSu0jZSX1/…
Shaggy

2

Gelée , 12 , 11 octets

QLn⁵
ḤÇпL’

Essayez-le en ligne!

Dois aller vite!

Explication:

        # Helper link, takes one argument 'z'
Q       # The unique digits of 'z'
 L      # Length
  n     # Does not equal
   ⁵    # 10
        #
        # Main link
  п    # While <condition> is true, run <body> and return all intermediate results
        # Condition:
 Ç      #   The helper link
        # Body:
Ḥ       #   Double the input
        # Now we have a list of all the 'z's that we passed to the helper link
    L   # Return it's length
     ’  # minus one




2

Haskell, 44 octets

until(\c->all(`elem`show(n*2^c))['0'..'9'])(+1)0

2

Clojure, 115 89 82 octets

-26 octets en utilisant simplement une chaîne pour représenter la liste des caractères (duh, rétrospectivement), et en passant de l'utilisation de la récursivité à loop, ce qui m'a permis de faire quelques optimisations.

-7 octets en supprimant l'appel à bigint. Apparemment, nous devons seulement gérer les entrées qui ne provoqueront pas de débordement.

#(loop[n % c 0](if(empty?(remove(set(str n))"1234567890"))c(recur(* 2 n)(inc c))))

Prégolfé:

(defn pan [num]
  (loop [n num
         cnt 0]

    ; Remove all the characters from the stringified input
    ;  that are numeric. If the result is an empty list, all
    ;  the numbers were present.
    (if (empty? (remove (set (str n)) "1234567890"))
      cnt
      (recur (* 2 n) (inc cnt)))))

Vous pouvez économiser 7 octets en utilisant every?au lieu de empty? (remove …:#(loop[n % c 0](if(every?(set(str n))"1234567890")c(recur(* 2 n)(inc c)))))
bfontaine

@bfontaine Oh, tu as raison! Merci. Je vais arranger ça plus tard. Merci.
Carcigenicate

2

Rétine , 85 octets

^\d*
$&¶$&
D`.(?=.*¶)
\d{10}¶\d+|\d*¶

[5-9]
#$&
T`d`EE
T`_d#`d_`\d#
#
1
}`\d\b
$&@
@

Essayez-le en ligne!Le lien inclut des cas de test. Légèrement optimisé pour l'exécution. Explication:

^\d*
$&¶$&

Dupliquez le numéro saisi.

D`.(?=.*¶)

Dédupliquez les chiffres de la première copie.

\d{10}¶\d+|\d*¶

S'il reste 10 chiffres, supprimez les deux numéros, sinon supprimez simplement la première copie. Notez que la suppression des deux nombres entraîne l'interruption du reste de la boucle.

[5-9]
#$&

Placer un # avant les gros chiffres.

T`d`EE

Doublez chaque chiffre.

T`_d#`d_`\d#

Ajoutez les portages.

#
1

Traitez avec un transport de premier plan.

}`\d\b
$&@

Ajouter un @ boucle et jusqu'à ce que les 10 chiffres soient trouvés.

@

Imprimez le nombre de @s ajoutés.


2

APL (Dyalog Unicode) , 19 + 2 = 21 octets

0∘{∧/⎕D∊⍕⍵:⍺⋄⍺+12×⍵}

Essayez-le en ligne!

Ceci est un dyadique Dfn( d IRECT f unctio n ), en prenant 0 comme argument de gauche et le nombre entier en tant que droit. Étant donné que l'entrée est censée être uniquement l'entier, j'ai ajouté 2 octets pour l'argument0∘ au nombre d'octets.

f← n'est pas inclus dans le nombre d'octets, car ce n'est pas nécessaire . Cela facilite simplement la construction des cas de test.

Comment ça fonctionne:

Les en-têtes: j'ai supprimé ceux du nombre d'octets après avoir discuté dans la salle APL, car la fonction fait ce qu'elle est censée faire et les résultats ne sont incorrects qu'en raison des paramètres par défaut du REPL d'APL.

⎕FR←1287Définit la représentation F loat R sur une décimale de 128 bits (7 est le code pour la décimale dans le REPL d'APL). ⎕PP←34Définit le P Rint P recision à 34 chiffres. Les deux sont nécessaires, car la représentation par défaut d'APL pour les grands nombres les transforme en notation scientifique (par exemple, 3.14159265359E15), ce qui gâche énormément le code.

0∘{∧/⎕D∊⍕⍵:⍺⋄⍺+12×⍵}  Dyadic Dfn
0                      Fixes 0 as the left argument  
          :             If
     D                 String representation of all digits [0, 9]
                       "is in"
        ⍕⍵              String representation of the input
   ∧/                   AND-reduction. Yields 1 (true) iff all digits are in the right argument.
                       return the left argument
                       Else
                 2×⍵    Double the right arg
             ⍺+1        increment the left arg
                       Recursively call this function with the new arguments.

2

Java 8, 132 110 87 74 octets

n->{int c=0;for(;(n+"").chars().distinct().count()!=10;n*=2)c++;return c;}

-57 octets grâce à @ OlivierGrégoire .

Explication:

Essayez-le ici. (Remarque: le cas de test pour 2est désactivé car il devrait s'arrêter à 2 68 , mais la taille de longest limitée à 2 63 -1.)

n->          // Method with long parameter and integer return-type
  int c=0;   //  Count-integer, starting at 0
  for(;(n+"").chars().distinct().count()!=10;
             //  Loop (1) as long as the unique amount of digits in the number are not 10
    n*=2)    //    After every iteration: multiply the input by 2
   c++;      //   Increase the count by 1
             //  End of loop (1) (implicit / single-line body)
  return c;  //  Return the counter
}            // End of method

Les anciens 132 octets répondent en utilisant une Stringentrée et une expression régulière:

n->f(n,0)int f(String n,int c){String t="";for(int i=0;i<10;t+="(?=.*"+i+++")");return n.matches(t+".*")?c:f(new Long(n)*2+"",c+1);}

Essayez-le ici. (Remarque: le cas de test pour 2est désactivé car il provoque une StackOverflowException en raison d'un peu trop de récursivité.)

Le regex total pour vérifier si la chaîne contient les 9 chiffres devient ^(?=.*0)(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5)(?=.*6)(?=.*7)(?=.*8)(?=.*9).*$, ce qui utilise une anticipation positive pour la chaîne entière.


1
111 octets (yup, le nombre d'octets est un "uni-numérique" ;-)
Olivier Grégoire

Notez que 2 ne fonctionnera jamais parce que nous attendons 2^68comme premier numéro pandigital, mais les longs en Java sont limités à 2^63-1.
Olivier Grégoire

1
87 octets . Merci reduce\ o /
Olivier Grégoire

1
74 octets . Arrêt ici ;-)
Olivier Grégoire

1
@KevinCruijssen Je sais que vous avez effacé votre ancienne méthode, mais je veux juste souligner que vous pouvez utiliser l'expression (?:.*?(\d)(?!.*\1)){10}
régulière

1

Husk , 10 octets

←Vö>9Lud¡D

Essayez-le en ligne!

Explication

        ¡D    Repeatedly double the input, collecting results in a list
 V            Return the first index where the following is true
     L          The length of
       d        the digits
      u         with duplicates removed
  ö>9           is greater than 9
←             Decrement (as Husk uses 1-indexing)

1

Mathematica, 59 48 47 46 38 octets

-9 octets grâce à Jenny_mathy.

If[!FreeQ[DigitCount@#,0],#0[2#]+1,0]&

Essayez-le en ligne en utilisant les mathématiques!


2
46 octets: Si [Tr [1 ^ Union @ IntegerDigits @ #] <10, # 0 [2 #] + 1,0] &
J42161217

Mathematica permet des fonctions récursives anonymes. :Oh merci!
totalement humain

2
38 octets: Si [! FreeQ [DigitCount @ #, 0], # 0 [2 #] + 1,0] &
J42161217

Oh merci! BTW, `` peut être utilisé pour le code mais les espaces blancs de tête ne sont pas autorisés. afonctionnera mais «a» ne fonctionnera pas.
totalement humain

BTW vous pouvez utiliser ce pied de page dans TIO Print/@f/@{617283945,2,66833,1234567890,100,42}
J42161217

1

R , 74 octets

function(x){while(!all(0:9%in%el(strsplit(c(x,""),"")))){F=F+1;x=2*x};F*1}

Essayez-le en ligne! Notez que R donnera la mauvaise réponse àf(2) raison des limitations de la façon dont le langage stocke les grands entiers.

Explication: Pour le test de pandigitalité, l'entrée est contrainte à un vecteur de caractères en se joignant à une chaîne vide, puis divisée en chiffres individuels. Nous vérifions ensuite si tous les 0: 9 sont présents dans le vecteur résultant; sinon, nous incrémentons le compteur, doublons l'entrée et répétons.

Le compteur utilise F qui s'initialise comme FAUX. Pour vous assurer qu'il est contraint en numérique, nous multiplions par un avant de revenir.


l'utilisation c(x,"")est une astuce el(strsplit(...))
Giuseppe

1

PowerShell , 70 69 octets

for($n=[bigint]$args[0];([char[]]"$n"|group).count-le9;$n*=2){$i++}$i

Essayez-le en ligne!

(Près de deux fois plus longtemps que la réponse Python: - \)

Prend des données $args[0], les transforme en un [bigint], les enregistre $n. Entre dans une forboucle. À chaque itération, nous vérifions si l' $nombre convertie en chaîne, puis en chartableau, lorsqu'elle Group-Objectest ensemble, a un .count -less than ou equal to 9. Autrement dit, la seule façon qu'il soit égal à 10 est si au moins un chiffre de chaque nombre 1234567890est présent. Si oui, nous sortons de la boucle. Sinon, nous $n*=2continuons. À chaque itération à l'intérieur de la boucle, nous incrémentons simplement $i. Lorsque nous quittons la boucle, nous sortons simplement$i .

Notez que pour l' entrée comme 1234567890où chaque chiffre est déjà pris en compte, cela ne de sortie, ce qui est une valeur Falsey dans PowerShell, et équivalent à 0quand il est lancé comme [int]. Si ce n'est pas OK, nous pouvons simplement mettre un +devant la sortie $ipour le convertir explicitement en entier.

Un octet enregistré grâce à Roland Heath.


Pourriez-vous utiliser le9 au lieu de ne10? Je ne connais pas le PowerShell, mais cela pourrait économiser un octet.
Roland Heath

@RolandHeath Effectivement; bon appel. Merci!
AdmBorkBork



0

Perl, 43 + 1 octets

for$x(0..9){$_*=2,++$\,redo LINE if!/$x/}}{

Utilisation du -pdrapeau. Cela s'appuie sur la solution fournie par Xcali ci-dessus.


0

Swift 4 , 111 octets

func p(_ x:Int,_ c:Int=0)->Int{if !(String(Set(String(x)).sorted())=="0123456789"){return p(x*2,c+1)};return c}

Remarque: ne fonctionnera pas pour x = 2, en raison d'un débordement.

Explication - L'entrée x est d'abord transtypée en chaîne. Ensuite, Set () supprime les caractères répétitifs. Ensuite, il est trié pour correspondre au résultat. S'il ne correspond pas, x est double et le compteur est incrémenté.


1
il ne fonctionne pas car la var est de 64 bits. Il y a beaucoup d'autres réponses avec le même problème.
Naresh


Si vous pensez que cela devrait être autorisé, apportez-le au PO. Cela peut être une pratique courante, mais le PO ne l'a pas spécifiquement autorisé et les tests semblent suggérer que vous devez prendre en charge 2.
Post Rock Garf Hunter

1
@FunkyComputerMan en fait, j'ai autorisé les réponses qui ne peuvent pas gérer les nombres en dehors des limites de la langue, mais Shaggy semble avoir supprimé le commentaire demandant à ce sujet. Cette réponse est très bien.
caird coinheringaahing

0

Rubis, 46 45 39 38 octets

def f n;n.digits.uniq[9]?0:1+f(n*2)end

Essayez-le en ligne!

Mises à jour:

  1. -1 en utilisant def f n;au lieu de def f(n);.
  2. -6 en utilisant …[9]au lieu de….size==10
  3. -1 en supprimant un point-virgule

0

Japt , 15 octets

LÆ*2pXÃbì_â Ê¥A

Essayez-le


Explication

Saisie implicite d'entier U.

LÆ    Ã

Créez un tableau d'entiers de 0à 99et passez chacun par une fonction où Xest l'élément courant.

*2pX

U multiplié par 2 élevé à la puissance de X .

b

Récupère l'index du premier élément qui retourne vrai lorsqu'il est passé par la fonction suivante.

ì_â

Divisez-vous en un tableau de chiffres et supprimez les doublons.

Ê¥A

Obtenez la longueur du tableau et vérifiez l'égalité avec 10 .


Alternative, 15 octets

@*2pX)ìâ sÊ¥A}a

Essayez-le


Explication

Saisie implicite d'entier U.

@            }a

En commençant par 0, renvoyez le premier nombre qui retourne vrai lorsqu'il est passé par la fonction suivante, avec Xétant le nombre actuel.

*2pX)

Comme ci-dessus, multipliez Upar 2 la puissance de X.

ìâ

Fractionner en un tableau de chiffres, supprimer les doublons et rejoindre à un entier.

Convertissez en chaîne, obtenez la longueur et reconvertissez en entier.

¥A

Vérifiez l'égalité avec 10.


0

QBIC , 48 octets, nc

{q=1[z|q=q*instr(!:$,!a-1$)]~q>0|_Xp\p=p+1┘b=b*2

Cela devrait fonctionner, en théorie. Cependant, en pratique, cela échoue parce que QBasic convertit les nombres à dix chiffres (au moins nécessaires pour obtenir tous les chiffres) en notation scientifique ... Je l'ai marqué comme non concurrent à cause de cela.

Explication

{             DO ad infinitum
q=1           set q to 1
[z|           FOR a = 1 to 10
q=q*instr     multiply q by the position
(!:$             - in 'b' (read from cmd line at start) cast to string (! ... $)
,!a-1$)          - of the number a-1 [0-9] cast to string
]             NEXT
~q>0          IF any character was not found, instr gave a 0. If q != 0 all digits were present
|_Xp          THEN quit, printing  p (is 0 at start)
\p=p+1        ELSE increase step counter p
┘b=b*2        and double 'b'

0

GNU dc, 61 octets

L'entrée est copiée du haut de la pile (qui doit être autrement vide); la sortie est poussée en haut de la pile.

[I~1r:ad0<s]ss[d1+r;a1=p]sp[d2*lfx]sh[0Sadlsxlpx11!=h]dsfxz1-

Explication

Nous utilisons la variable tableau a, stockant un 1 dans a[d]si le chiffre dest présent, sinon retombant à 0 là. Nous utilisons l'extension GNU ~pour obtenir le quotient et le reste dans une seule commande.

# populate a[0-9] from the digits
[I~1r:ad0<s]ss

# check pandigit
# return 1 more than lowest unset element of a[]
# start with stack=0
[d1+r;a1=p]sp

# Test for pandigit; double and repeat if needed
[dd+lfx]sh
[0Sadlsxlpx11!=h]dsfx

# We left one value on the stack for each doubling, plus the original
z1-

En prime, cela fonctionnera dans des bases de nombres arbitraires (pas seulement décimales): définissez simplement le radix d'entrée comme requis (la constante 11dans la définition de fsera lue en utilisant cette base de nombres, elle est donc automatiquement correcte).

Tester

for i in 617283945 2 66833 1234567890 100 42
do
    printf '%s => ' $i
    dc -e $i \
       -e '[I~1r:ad0<s]ss[d1+r;a1=p]sp[dd+lfx]sh[0Sadlsxlpx11!=h]dsfxz1-' \
       -e p
done
617283945 => 1
2 => 67
66833 => 44
1234567890 => 0
100 => 51
42 => 55

0

REXX, 57 octets

arg n
do b=0 while verify(0123456789,n)>0
  n=n*2
  end
say b

0

q / kdb + , 33 octets

Solution:

(#)1_{x*2 1 min!:[10]in 10 vs x}\

Exemples:

q)(#)1_{x*2 1 min!:[10]in 10 vs x}\[100]
51
q)(#)1_{x*2 1 min!:[10]in 10 vs x}\[1234567890]
0
q)(#)1_{x*2 1 min!:[10]in 10 vs x}\[42]
55

Explication:

Tous les octets sont dans l'égalité, pourraient être en mesure de jouer un peu plus loin. Utilise l' scanadverbe de q :

count 1_{x*2 1 min til[10] in 10 vs x}\ / ungolfed solution
        {                            }\ / scan over this lambda until it yields same result
                              10 vs x   / convert to base 10
                           in           / left list in right list, returns boolean list
                   til[10]              / range 0..9
               min                      / return the minimum of the list, 0 or 1
           2 1                          / list (2;1) indexed into with 0 or 1
         x*                             / return x multiplied by either 2 or 1
      1_                                / 1 drop, drop one element from front of list
count                                   / count the length of the list

Remarques:

Si nous passons à l' kinvite, nous pouvons avoir une solution de 25 octets. Convertit le nombre en une liste de caractères:

q)\
  #1_{x*2 1@&/($!10)in$$x}\[100]
51
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.