Raddoppio pandigitale


14

Ispirato da questa CMC

Dato un numero intero positivo maggiore di 0, eseguire la seguente operazione su di esso:

  • Se tutte e dieci le cifre singole ( 1234567890) sono nel numero almeno una volta, emettere il conteggio ed uscire dal programma
  • Altrimenti, raddoppia il numero e ripeti, aumentando il conteggio.

Il conteggio inizia da 0 ed è il numero di volte in cui l'ingresso è stato raddoppiato. Ad esempio, se l'input fosse 617283945, dovrebbe essere raddoppiato una volta perché 1234567890 contiene tutte e 10 le cifre.

Questo è un quindi vince il codice più breve. L'input può essere preso come una stringa, se lo si desidera.

Casi test

input => output

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

Possiamo prendere l'input come una stringa?
Stephen,

@Stephen puoi prendere l'input come stringa.
caird coinheringaahing

3
È garantito che per qualcuno nesiste qualcosa di ksimile che nkè pandigitale? Mi piacerebbe vedere una prova.
shooqie,

1
@bfontaine Chat Mini Challenge
caird coinheringaahing,

3
@shooqie Proof! Per ogni n che è coprime a 10, è anche coprime a 10 ^ 10, e quindi esiste qualche k tale che nk è 1 mod 10 ^ 10. Quindi 1234567890 * nk = 1234567890 mod 10 ^ 10, quindi ogni cifra appare necessariamente almeno una volta. In caso contrario, moltiplicare per 2, 5 o 25 in base alle necessità per rendere l'ultimo coprimo a cifre diverse da zero con 10 e una variante delle prove di cui sopra funziona (formalmente, n = 10 ^ m * p, dove p soddisfa la condizione di cui sopra , quindi 1234567890 * p * k come sopra è pandigitale, quindi 1234567890 * p * k * 10 ^ m = 1234567890 * k * n è). :)
B. Mehta,

Risposte:



4

J , 24 23 byte

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

Provalo online!

Spiegazione

(]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

Bello. Ero bloccato sulla raccolta dei risultati, non pensavo di usare quel tipo di funzione ricorsiva.
Conor O'Brien,

4

05AB1E , 11 10 byte

-1 byte grazie a scottinet

[D9ÝåË#·]N

Provalo online! o come una suite di test

[          // 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 Grazie! Non so come mi sia perso.
Riley,

@Riley stava per dire use xma anche quello è 10 ... Bella risposta. Il pensiero se xne libererebbe D, ma è la stessa idea.
Magic Octopus Urn,

3

Perl 6 ,31 28 byte (27 caratteri)

-3 byte grazie a @Joshua

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

Provalo online!

Spiegazione: Sempre lo stesso costrutto per generare ricorsivamente elenchi. Il primo elemento è il numero indicato ( $_), ogni elemento successivo è 2 volte il precedente ( 2×*- usiamo ×, perché, sebbene il carattere a 2 byte, sia ancora 1 byte più economico di 2 * *), e lo facciamo fino a quando la condizione finale di *.comb.unique>9è soddisfatta , ovvero quando nel numero sono presenti più di 9 caratteri univoci. (Tecnicamente, suddividiamo la stringa in un elenco di caratteri con .comb, la forziamo in un set con .Set(ovviamente, I set contengono ogni elemento una sola volta) e confrontiamo con 9, che forza il set in un contesto numerico, che a sua volta dà il suo numero di elementi.)

Infine, sottraggiamo 1 da questo elenco. Ancora una volta, l'elenco viene forzato in un contesto numerico, quindi ciò che restituiamo è 1 in meno della lunghezza di tale elenco.


È possibile utilizzare .Setinvece di .uniquesalvare 3 byte.
Giosuè,

@ Giosuè, buon punto! Grazie. Non ci avevo mai pensato.
Ramillies,

3

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

Grazie @ ConorO'Brien per aver salvato 10 byte suggerendo big.js invece di bignumber.js
Grazie a @Rick Hitchcock per -1 byte
Grazie a @Shaggy per -3 byte

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

Accetta l'input come stringa; supporta fino a circa 2 69 a causa della conversione automatica della notazione scientifica avvenuta oltre quel punto.

Test snippet

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>

Intervallo infinito, 106 88 87 84 byte

Usando l'opzione di configurazione per disabilitare efficacemente la notazione scientifica durante la conversione di numeri in stringhe, possiamo avere un intervallo quasi infinito.


Forse potresti accorciare il BigNumberbit usando big.js ?
Conor O'Brien,

@ ConorO'Brien Questo sarà sicuramente d'aiuto, soprattutto perché newè facoltativo in quello. Aggiornerò, grazie!
Justin Mariner,

Salva un byte con f=n=>[..."0123456789"].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2)).
Rick Hitchcock,

Non abbiamo bisogno di gestire grandi numeri interi in modo da poter rilasciare big.js se lo desideri, portandoti a 61 byte. E puoi salvare 3 byte sostituendo la stringa di cifre con "4"+2**29: tio.run/##BcGxDkAwEADQb2GQO41LNBZDbX7AKgbhKkSu0jZSX1/…
Shaggy

2

Gelatina , 12 , 11 byte

QLn⁵
ḤÇпL’

Provalo online!

Devo andare veloce!

Spiegazione:

        # 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 byte

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

2

Clojure, 115 89 82 byte

-26 byte semplicemente usando una stringa per rappresentare l'elenco di caratteri (duh, in retrospettiva) e passando dall'uso della ricorsione a loop, che mi ha permesso di fare un paio di ottimizzazioni.

-7 byte eliminando la chiamata a bigint. Apparentemente abbiamo solo bisogno di gestire input che non causeranno un overflow.

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

Pregolfed:

(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)))))

Puoi salvare 7 byte usando every?invece di empty? (remove …:#(loop[n % c 0](if(every?(set(str n))"1234567890")c(recur(* 2 n)(inc c)))))
bfontaine,

@bfontaine Oh, hai ragione! Grazie. Lo aggiusterò più tardi. Grazie.
Carcigenicate,

2

Retina , 85 byte

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

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

Provalo online! Il link include casi di test. Leggermente ottimizzato per il tempo di esecuzione. Spiegazione:

^\d*
$&¶$&

Duplica il numero di input.

D`.(?=.*¶)

Deduplica le cifre nella prima copia.

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

Se rimangono 10 cifre, cancella entrambi i numeri, altrimenti elimina solo la prima copia. Si noti che l'eliminazione di entrambi i numeri causa il resto del ciclo in modalità non operativa.

[5-9]
#$&

Inserire un #prima di cifre grandi.

T`d`EE

Raddoppia ogni cifra.

T`_d#`d_`\d#

Aggiungi nel carry.

#
1

Affronta un carry principale.

}`\d\b
$&@

Aggiungi an @e loop fino a trovare tutte e 10 le cifre.

@

Stampa il numero di @s aggiunti.


2

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

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

Provalo online!

Si tratta di un diadica Dfn( d ire f unctio n ), prendendo come argomento 0 sinistro e il numero intero come il diritto. Dato che l'input dovrebbe essere solo il numero intero, ho aggiunto 2 byte per l'argomento0∘ al conteggio dei byte.

f← non è incluso nel conteggio dei byte, poiché non lo è necessario . Semplifica semplicemente la creazione dei casi di test.

Come funziona:

Le intestazioni: ho rimosso quelle dal conteggio dei byte dopo alcune chat nella stanza APL, poiché la funzione fa quello che dovrebbe fare ei risultati sono errati solo a causa delle impostazioni predefinite del REPL di APL.

⎕FR←1287Imposta la rappresentazione F loat R su 128-decimale (7 è il codice per i decimali nel REPL di APL). ⎕PP←34Imposta il P tampa P recision a 34 cifre. Entrambi sono necessari, poiché la rappresentazione predefinita di APL per i grandi numeri li trasforma in notazione scientifica (ad es. 3.14159265359E15) che incasina il codice alla grande.

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 byte

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

-57 byte grazie a @ OlivierGrégoire .

Spiegazione:

Provalo qui. (Nota: il test case per 2è disabilitato perché dovrebbe fermarsi a 2 68 , ma la dimensione di longè limitata a 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

I vecchi 132 byte rispondono usando un Stringinput e regex:

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);}

Provalo qui. (Nota: il test case per 2è disabilitato perché causa StackOverflowException a causa di un eccesso di ricorsione.)

La regex totale per verificare se la stringa contiene tutte e 9 le cifre diventa ^(?=.*0)(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5)(?=.*6)(?=.*7)(?=.*8)(?=.*9).*$, il che utilizza un aspetto positivo per l'intera stringa.


1
111 byte (sì, il conteggio dei byte è un "uni-digitale" ;-)
Olivier Grégoire

Si noti che 2 non funzionerà mai perché ci aspettiamo 2^68come primo numero pandigitale, ma i long in Java sono limitati a 2^63-1.
Olivier Grégoire,

1
87 byte . Grazie reduce\ o /
Olivier Grégoire il

1
74 byte . Fermarsi qui ;-)
Olivier Grégoire,

1
@KevinCruijssen So che hai cancellato il tuo vecchio metodo, ma voglio solo sottolineare che puoi usare la seguente regex per abbinare tutte e 10 le cifre:(?:.*?(\d)(?!.*\1)){10}
jaytea,

1

Buccia , 10 byte

←Vö>9Lud¡D

Provalo online!

Spiegazione

        ¡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 byte

-9 byte grazie a Jenny_mathy.

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

Provalo online usando Mathics!


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

Mathematica consente funzioni ricorsive anonime. : o Grazie!
totalmente umano il

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

Oh, grazie! A proposito, `` può essere utilizzato per il codice ma non è consentito lo spazio bianco iniziale. afunzionerà ma `a` non lo farà.
totalmente umano il

sure!BTW you can use this footer in TIO Print/@f/@{617283945,2,66833,1234567890,100,42}
J42161217

1

R, 74 bytes

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

Try it online! Note that R will give the wrong answer to f(2) due to limitations of how the language stores large integers.

Explanation: For the test of pandigitality, the input is coerced to a character vector by joining with an empty string and then split into individual digits. We then check whether all of 0:9 are present in the resulting vector; if not, we increment the counter, double the input and repeat.

The counter uses F which initialises as FALSE. To make sure it is coerced to numeric, we multiply by one before returning.


using c(x,"") is a neat trick for el(strsplit(...))
Giuseppe

1

PowerShell, 70 69 bytes

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

Try it online!

(Nearly twice as long as the Python answer :-\ )

Takes input $args[0], casts it as a [bigint], saves it to $n. Enters a for loop. Each iteration we check against whether the $number converted to a string then to a char-array, when Group-Object'd together, has a .count -less than or equal to 9. Meaning, the only way that it equals 10 is if at least one digit of every number 1234567890 is present. If yes, we exit the loop. If not, we $n*=2 and continue. Each iteration inside the loop, we're simply incrementing $i. When we exit the loop, we simply output $i.

Note that for input like 1234567890 where every digit is already accounted for, this will output nothing, which is a falsey value in PowerShell, and equivalent to 0 when cast as an [int]. If that's not OK, we can simply put a + in front of the output $i to explicitly cast it as an integer.

Saved a byte thanks to Roland Heath.


Could you use le9 instead of ne10? I'm not familiar with powershell, but that might save a byte.
Roland Heath

@RolandHeath Indeed; good call. Thanks!
AdmBorkBork



0

Perl, 43 + 1 bytes

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

Using the -p flag. This builds on the solution provided by Xcali above.


0

Swift 4, 111 bytes

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

Note: Won't work for x = 2, because of overflow.

Explanation - Input x is first typecasted to string. Then Set() removes the repeating characters. Then it is sorted to match the result. If it doesn't match, x is doubles and counter is incremented.


1
it doesn't wok because the var is 64 bits. There a lot of other answers with same problem.
Naresh


If you think that this should be allowed bring it up with the OP. It may be common practice but the OP has not specifically allowed it and the testcases seem to suggest you need to support 2.
Post Rock Garf Hunter

1
@FunkyComputerMan actually, I did allow answers that can't handle numbers outside the bounds of the language, but Shaggy seems to have deleted the comment asking about that. This answer is fine.
caird coinheringaahing

0

Ruby, 46 45 39 38 bytes

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

Try it online!

Updates:

  1. -1 by using def f n; instead of def f(n);.
  2. -6 by using …[9] instead of ….size==10
  3. -1 by removing a semicolon

0

Japt, 15 bytes

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

Try it


Explanation

Implicit input of integer U.

LÆ    Ã

Create an array of integers from 0 to 99 and pass each through a function where X is the current element.

*2pX

U multiplied by 2 raised to the power of X.

b

Get the index of the first element thay returns true when passed through the following function.

ì_â

Split to an array of digits and remove the duplicates.

Ê¥A

Get the length of the array and check for equality with 10.


Alternative, 15 bytes

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

Try it


Explanation

Implicit input of integer U.

@            }a

Starting with 0, return the first number that returns true when passed through the following function, with X being the current number.

*2pX)

As above, multiply U by 2 to the power of X.

ìâ

Split to an array of digits, remove duplicates and rejoin to an integer.

Convert to a string, get the length and convert back to an integer.

¥A

Check for equality with 10.


0

QBIC, 48 bytes, nc

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

This should work, in theory. However, in practice this fails because QBasic casts ten-digit numbers (at least needed to get all digits) to scientific notation... I've marked it as non-competing because of that.

Explanation

{             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 bytes

Input is copied from top of stack (which must be otherwise empty); output is pushed to top of stack.

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

Explanation

We use the array variable a, storing a 1 in a[d] if digit d is present, otherwise falling back to 0 there. We use the GNU extension ~ to obtain quotient and remainder in a single command.

# 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-

As a bonus, this will work in arbitrary number bases (not only decimal): simply set the input radix as required (the constant 11 in the definition of f will be read using that number base, so is automatically correct).

Test

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 bytes

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

0

q/kdb+, 33 bytes

Solution:

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

Examples:

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

Explanation:

All the bytes are in the equality, might be able to golf this one down a little further. Utilises q's scan adverb:

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

Notes:

If we drop to the k prompt then we can have a 25 byte solution. Converts the number to a list of characters:

q)\
  #1_{x*2 1@&/($!10)in$$x}\[100]
51
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.