Пандигітальне подвоєння


14

Натхненний цим CMC

Давши додатне ціле число більше 0, виконайте наступну операцію над ним:

  • Якщо всі десять однозначних цифр ( 1234567890) принаймні один раз містять число, виведіть підрахунок та вийдіть з програми
  • В іншому випадку подвойте число і повторіть, збільшуючи кількість.

Відлік починається з 0 і є числом подвоєння вводу. Наприклад, якби вхід був 617283945, його потрібно було б подвоїти один раз, тому що 1234567890 має в ньому всі 10 цифр.

Це тому виграє найкоротший код. Якщо ви хочете, введення даних може сприйматися як рядок.

Тестові справи

input => output

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

Чи можемо ми приймати введення як рядок?
Стівен

@Stephen Ви можете взяти введення як рядок.
caird coinheringaahing

3
Чи гарантується, що для будь-якого nіснує kтакий, який nkє пандігітальним? Я хотів би бачити докази.
shooqie

1
@bfontaine Chat Mini Challenge
caird coinheringaahing

3
@shooqie Доказ! Для будь-якого n, який є coprime до 10, це також coprime до 10 ^ 10, і тому існує деякий k такий, що nk 1 mod 10 ^ 10. Тоді 1234567890 * nk = 1234567890 mod 10 ^ 10, тому кожна цифра обов'язково з’являється хоча б один раз. Якщо ні, помножте на 2, 5 або 25, як потрібно, щоб зробити останній ненульовий копріум на 10, і варіант вищезазначеного доказування працює (формально, n = 10 ^ m * p, де p задовольняє вищевказаній умові , то 1234567890 * p * k, як зазначено вище, є пандігітальним, тому 1234567890 * p * k * 10 ^ m = 1234567890 * k * n є). :)
Б. Мехта

Відповіді:



4

J , 24 23 байти

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

Спробуйте в Інтернеті!

Пояснення

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

Приємно. Я застряг у збиранні результатів, не думав про використання такого типу рекурсивної функції.
Conor O'Brien

4

05AB1E , 11 10 байт

-1 байт завдяки скоттинету

[D9ÝåË#·]N

Спробуйте в Інтернеті! або як тестовий набір

[          // 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 Дякую! Я не знаю, як я це пропустив.
Райлі

@riley збирався сказати, use xале це теж 10 ... Приємна відповідь. Думка xпозбулася б D, але це та сама ідея.
Чарівна восьминога урна

3

Perl 6 ,31 28 байт (27 символів)

-3 байти завдяки @Joshua

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

Спробуйте в Інтернеті!

Пояснення: Ще одна і та ж конструкція для рекурсивного генерування списків. Перший елемент - це задане число ( $_), кожен наступний елемент у 2 рази перевищує попередній ( 2×*- ми використовуємо ×, тому що, хоча 2-байтний символ, це все-таки на 1 байт дешевше, ніж 2 * *), і ми робимо це до тих пір, поки кінцева умова не *.comb.unique>9буде задоволена , тобто коли в кількості більше 9 унікальних символів. (Технічно ми розбиваємо рядок до списку символів .comb, примушуємо його до набору з .Set(звичайно, набори містять кожен елемент лише один раз), і порівнюємо з 9, що змушує набір на числовий контекст, що в свою чергу дає його кількість елементів.)

Нарешті, з цього списку віднімаємо 1. Знову ж таки, список вимушений в числовий контекст, тому те, що ми повертаємо, на 1 менше, ніж довжина цього списку.


Ви можете використовувати .Setзамість того, .uniqueщоб зберегти 3 байти.
Джошуа

@ Джошуа, хороший момент! Дякую. Я ніколи про це не думав.
Раміллі

3

JavaScript (ES6) + big.js , 84 74 73 70 байт

Дякую @ ConorO'Brien за збереження 10 байт, запропонувавши big.js замість bignumber.js
Завдяки @Rick Hitchcock за -1 байт
Дякуємо @Shaggy за -3 байти

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

Приймає введення як рядок; підтримує приблизно 2 69 завдяки автоматичному перетворенню наукових позначень, що відбувається після цієї точки.

Тест-фрагмент

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>

Нескінченний діапазон, 106 88 87 84 байт

Використовуючи параметр config для ефективного відключення наукових позначень при перетворенні чисел у рядки, ми можемо мати майже нескінченний діапазон.


Можливо, ви могли вкоротити BigNumberшматочок за допомогою big.js ?
Conor O'Brien

@ ConorO'Brien Це, безумовно, допоможе, тим більше, що newце необов’язково в цьому. Буде оновлено, спасибі!
Джастін Марінер

Збережіть один байт за допомогою f=n=>[..."0123456789"].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2)).
Рік Хічкок

Нам не потрібно обробляти великі цілі числа, щоб ви могли скинути big.js, якщо хочете, збивши вас до 61 байта. А ви можете зберегти 3 байти, замінивши рядок цифр на "4"+2**29: tio.run/##BcGxDkAwEADQb2GQO41LNBZDbX7AKgbhKkSu0jZSX1/…
Shaggy

2

Желе , 12 , 11 байт

QLn⁵
ḤÇпL’

Спробуйте в Інтернеті!

Треба швидко йти!

Пояснення:

        # 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

Clojure, 115 89 82 bytes

-26 bytes by just using a string to represent the list of characters (duh, in retrospect), and changing from using recursion to loop, which allowed me to make a couple of optimizations.

-7 bytes by getting rid of the call to bigint. Apparently we only need to handle input that won't cause an 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)))))

You can save 7 bytes by using every? instead of empty? (remove …: #(loop[n % c 0](if(every?(set(str n))"1234567890")c(recur(* 2 n)(inc c)))))
bfontaine

@bfontaine Oh, you're right! Thanks. I'll fix that later. Thanks.
Carcigenicate

2

Retina, 85 bytes

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

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

Try it online! Link includes test cases. Slightly optimised for run time. Explanation:

^\d*
$&¶$&

Duplicate the input number.

D`.(?=.*¶)

Deduplicate the digits in the first copy.

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

If 10 digits remain, delete both numbers, otherwise just delete the first copy. Note that deleting both numbers causes the rest of the loop to no-op.

[5-9]
#$&

Place a # before large digits.

T`d`EE

Double each digit.

T`_d#`d_`\d#

Add in the carries.

#
1

Deal with a leading carry.

}`\d\b
$&@

Append an @ and loop until all 10 digits are found.

@

Print the number of @s added.


2

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

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

Try it online!

This is a dyadic Dfn (direct function), taking 0 as its left argument and the integer as the right. Since the input is supposed to be only the integer, I added 2 bytes for the argument 0∘ to the byte count.

f← is not included in the byte count, since it's not necessary. It just makes it easier to build the test cases.

How it works:

The headers: I removed those from the byte count after some chatting in the APL room, since the function does what it's supposed to do and the results are only incorrect because of the default settings of APL's REPL.

⎕FR←1287 Sets the Float Representation to 128-bit decimal (7 is the code for decimal in APL's REPL). ⎕PP←34 Sets the Print Precision to 34 digits. Both of these are needed, since APL's default representation for big numbers transforms them to scientific notation (e.g. 3.14159265359E15) which messes up the code big time.

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 bytes

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

-57 bytes thanks to @OlivierGrégoire.

Explanation:

Try it here. (Note: test case for 2 is disabled because it should stop at 268, but the size of long is limited to 263-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

Old 132 bytes answer using a String input and 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);}

Try it here. (Note: test case for 2 is disabled because it causes a StackOverflowException due to slightly too much recursion.)

The total regex to check if the String contains all 9 digits becomes ^(?=.*0)(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5)(?=.*6)(?=.*7)(?=.*8)(?=.*9).*$, which uses a positive look-ahead for the entire String.


1
111 bytes (yup, the byte count is a "uni-digital" ;-)
Olivier Grégoire

Note that 2 will never work because we expect 2^68 as first pandigital number, but longs in Java are limited to 2^63-1.
Olivier Grégoire

1
87 bytes. Thanks reduce \o/
Olivier Grégoire

1
74 bytes. Stopping here ;-)
Olivier Grégoire

1
@KevinCruijssen I know you obliterated your old method, but just want to point out that you can use the following regex to match all 10 digits: (?:.*?(\d)(?!.*\1)){10}
jaytea

1

Husk, 10 bytes

←Vö>9Lud¡D

Try it online!

Explanation

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

-9 bytes thanks to Jenny_mathy.

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

Try it online using Mathics!


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

Mathematica allows for anonymous recursive functions. :o Thanks!
totallyhuman

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

Oh, thanks! BTW, ` ` can be used for code but leading whitespace is not allowed. a will work but ` a` won't.
totallyhuman

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

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.