Menggandakan Pandigital


14

Terinspirasi oleh CMC ini

Dengan bilangan bulat positif lebih besar dari 0, lakukan operasi berikut di atasnya:

  • Jika semua sepuluh digit tunggal ( 1234567890) berada dalam angka setidaknya sekali, hasilkan penghitungan dan keluar dari program
  • Jika tidak, gandakan jumlahnya dan ulangi, menambah hitungan.

Hitungan dimulai pada 0 dan berapa kali input digandakan. Misalnya, jika inputnya adalah 617283945, itu harus digandakan sekali karena 1234567890 memiliki semua 10 digit di dalamnya.

Ini adalah sehingga kode terpendek menang. Input dapat diambil sebagai string, jika Anda mau.

Uji kasus

input => output

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

Bisakah kita mengambil input sebagai string?
Stephen

@Stephen Anda dapat mengambil input sebagai string.
caird coinheringaahing

3
Apakah dijamin nada sesuatu kyang nkpandigital? Saya ingin sekali melihat bukti.
shooqie

1
@bfontaine Chat Mini Challenge
caird coinheringaahing

3
@shooqie Proof! Untuk setiap n yang merupakan koprime ke 10, itu juga coprime ke 10 ^ 10, dan ada beberapa k sedemikian sehingga nk adalah 1 mod 10 ^ 10. Kemudian 1234567890 * nk = 1234567890 mod 10 ^ 10, sehingga setiap digit muncul setidaknya satu kali. Jika tidak, kalikan dengan 2, 5, atau 25 seperlunya untuk membuat koprime non-nol angka terakhir dengan 10, dan varian dari karya bukti di atas (secara formal, n = 10 ^ m * p, di mana p memenuhi syarat di atas , maka 1234567890 * p * k seperti di atas adalah pandigital, jadi 1234567890 * p * k * 10 ^ m = 1234567890 * k * n adalah). :)
B. Mehta

Jawaban:



4

J , 24 23 byte

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

Cobalah online!

Penjelasan

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

Bagus. Saya terjebak dalam mengumpulkan hasil, tidak berpikir tentang menggunakan fungsi rekursif jenis itu.
Conor O'Brien

4

05AB1E , 11 10 byte

-1 byte berkat skottinet

[D9ÝåË#·]N

Cobalah online! atau sebagai Test Suite

[          // 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 Terima kasih! Saya tidak tahu bagaimana saya melewatkan itu.
Riley

@iley akan mengatakan use xtapi itu juga 10 ... Jawaban yang bagus. Pikiran xakan dihilangkan D, tapi itu ide yang sama.
Magic Gurita Guci

3

Perl 6 ,31 28 byte (27 karakter)

-3 byte terima kasih kepada @ Yosua

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

Cobalah online!

Penjelasan: Konstruk yang masih sama untuk menghasilkan daftar secara rekursif. Elemen pertama adalah angka yang diberikan ( $_), setiap elemen berikutnya adalah 2 kali dari sebelumnya ( 2×*- kita menggunakan ×, karena, walaupun karakter 2 byte, itu masih 1 byte lebih murah daripada 2 * *), dan kita melakukan ini sampai kondisi akhir *.comb.unique>9terpenuhi , yaitu ketika ada lebih dari 9 karakter unik dalam angka. (Secara teknis, kami memecah string ke daftar karakter dengan .comb, memaksanya ke set dengan .Set(tentu saja, Set berisi setiap elemen hanya sekali), dan membandingkan dengan 9, yang memaksa set ke dalam konteks numerik, yang pada gilirannya memberikan jumlah elemennya.)

Akhirnya, kita kurangi 1 dari daftar ini. Sekali lagi, daftar dipaksa ke dalam konteks numerik, jadi apa yang kita kembalikan adalah 1 kurang dari panjang daftar itu.


Anda dapat menggunakan .Setalih-alih .uniquemenyimpan 3 byte.
Joshua

@ Yosua, poin bagus! Terima kasih. Saya tidak pernah memikirkan hal ini.
Ramillies

3

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

Terima kasih @ ConorO'Brien untuk menghemat 10 byte dengan menyarankan big.js daripada bignumber.js
Terima kasih kepada @Rick Hitchcock untuk -1 byte
Terima kasih kepada @Shaggy untuk -3 byte

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

Mengambil input sebagai string; mendukung hingga sekitar 2.69 karena konversi notasi ilmiah otomatis terjadi di luar titik itu.

Cuplikan Tes

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>

Kisaran tak terbatas, 106 88 87 84 byte

Dengan menggunakan opsi konfigurasi untuk secara efektif menonaktifkan notasi ilmiah ketika mengubah angka menjadi string, kita dapat memiliki rentang yang hampir tak terbatas.


Mungkin Anda bisa mempersingkat BigNumberbit dengan menggunakan big.js ?
Conor O'Brien

@ ConorO'Brien Itu pasti akan membantu, terutama karena newbersifat opsional dalam hal itu. Akan diperbarui, terima kasih!
Justin Mariner

Simpan satu byte dengan f=n=>[..."0123456789"].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2)).
Rick Hitchcock

Kami tidak perlu menangani bilangan bulat besar sehingga Anda bisa menjatuhkan big.js jika Anda mau, membawa Anda ke 61 byte. Dan Anda dapat menyimpan 3 byte dengan mengganti string digit"4"+2**29 : tio.run/##BcGxDkAwEADQb2GQO41LNBZDbX7AKgbhKkSu0jZSX1/…
Shaggy

2

Jelly , 12 , 11 byte

QLn⁵
ḤÇпL’

Cobalah online!

Harus cepat!

Penjelasan:

        # 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 dengan hanya menggunakan string untuk mewakili daftar karakter (ya, dalam retrospeksi), dan berubah dari menggunakan rekursi menjadi loop , yang memungkinkan saya untuk membuat beberapa optimasi.

-7 byte dengan menyingkirkan panggilan ke bigint. Tampaknya kita hanya perlu menangani input yang tidak akan menyebabkan 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)))))

Anda dapat menyimpan 7 byte dengan menggunakan every?alih-alih empty? (remove …:#(loop[n % c 0](if(every?(set(str n))"1234567890")c(recur(* 2 n)(inc c)))))
bfontaine

@fontaine Oh, kau benar! Terima kasih. Saya akan memperbaikinya nanti. Terima kasih.
Carcigenicate

2

Retina , 85 byte

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

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

Cobalah online! Tautan termasuk kasus uji. Dioptimalkan sedikit untuk jangka waktu. Penjelasan:

^\d*
$&¶$&

Gandakan nomor input.

D`.(?=.*¶)

Mengurangi digit dalam salinan pertama.

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

Jika 10 digit tetap, hapus kedua angka, atau hapus salinan pertama. Perhatikan bahwa menghapus kedua angka menyebabkan sisa loop menjadi tanpa-op.

[5-9]
#$&

Tempatkan #sebelum angka besar.

T`d`EE

Gandakan setiap digit.

T`_d#`d_`\d#

Tambahkan dalam membawa.

#
1

Berurusan dengan carry terkemuka.

}`\d\b
$&@

Tambahkan a @dan loop sampai semua 10 digit ditemukan.

@

Cetak jumlah yang @ditambahkan.


2

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

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

Cobalah online!

Ini adalah diad Dfn( d irect f unctio n ), mengambil 0 sebagai argumen kirinya dan integer sebagai kanan. Karena input seharusnya hanya bilangan bulat, saya menambahkan 2 byte untuk argumen 0∘ke jumlah byte.

f←tidak termasuk dalam hitungan byte, karena itu tidak perlu . Itu hanya membuatnya lebih mudah untuk membangun test case.

Bagaimana itu bekerja:

Header: Saya menghapus yang dari jumlah byte setelah beberapa mengobrol di ruang APL, karena fungsi melakukan apa yang seharusnya dilakukan dan hasilnya hanya salah karena pengaturan default REPL APL.

⎕FR←1287Mengatur representasi F loat R ke desimal 128-bit (7 adalah kode untuk desimal dalam REPL APL). ⎕PP←34Menetapkan P etak P recision ke 34 digit. Kedua hal ini diperlukan, karena representasi default APL untuk angka besar mengubahnya menjadi notasi ilmiah (mis. 3.14159265359E15) yang mengacaukan kode waktu besar.

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 terima kasih kepada @ OlivierGrégoire .

Penjelasan:

Coba di sini. (Catatan: test case untuk 2dinonaktifkan karena harus berhenti di 2 68 , tetapi ukuran longterbatas pada 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

Old 132 byte menjawab menggunakan Stringinput dan 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);}

Coba di sini. (Catatan: test case untuk 2dinonaktifkan karena menyebabkan StackOverflowException karena rekursi yang sedikit terlalu banyak.)

Regex total untuk memeriksa apakah String berisi semua 9 digit menjadi ^(?=.*0)(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5)(?=.*6)(?=.*7)(?=.*8)(?=.*9).*$, yang menggunakan pandangan positif ke depan untuk seluruh String.


1
111 byte (ya, hitungan byte adalah "uni-digital" ;-)
Olivier Grégoire

Perhatikan bahwa 2 tidak akan pernah berfungsi karena kami berharap 2^68sebagai angka pandigital pertama, tetapi rindu di Jawa terbatas 2^63-1.
Olivier Grégoire

1
87 byte . Terima kasih reduce\ o /
Olivier Grégoire

1
74 byte . Berhenti di sini ;-)
Olivier Grégoire

1
@KevinCruijssen Saya tahu Anda menghapus metode lama Anda, tetapi hanya ingin menunjukkan bahwa Anda dapat menggunakan regex berikut untuk mencocokkan semua 10 digit:(?:.*?(\d)(?!.*\1)){10}
jaytea

1

Sekam , 10 byte

←Vö>9Lud¡D

Cobalah online!

Penjelasan

        ¡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 berkat Jenny_mathy.

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

Cobalah online menggunakan Matematika!


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

Mathematica memungkinkan untuk fungsi rekursif anonim. : o Terima kasih!
totallyhuman

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

Oh terima kasih! BTW, `` dapat digunakan untuk kode tetapi memimpin spasi tidak diizinkan. aakan bekerja tetapi `a` tidak akan.
totallyhuman

tentu! BTW Anda dapat menggunakan Print/@f/@{617283945,2,66833,1234567890,100,42}
catatan

1

R , 74 byte

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

Cobalah online! Perhatikan bahwa R akan memberikan jawaban yang salahf(2) karena keterbatasan bagaimana bahasa menyimpan bilangan bulat besar.

Penjelasan: Untuk uji pandigitalitas, input dipaksa ke vektor karakter dengan bergabung dengan string kosong dan kemudian dibagi menjadi digit individu. Kami kemudian memeriksa apakah semua 0: 9 ada dalam vektor yang dihasilkan; jika tidak, kami menambah penghitung, menggandakan input dan mengulangi.

Penghitung menggunakan F yang diinisialisasi sebagai FALSE. Untuk memastikan itu dipaksa numerik, kami mengalikannya dengan satu sebelum kembali.


menggunakan c(x,"")adalah trik yang rapi untukel(strsplit(...))
Giuseppe

1

PowerShell , 70 69 byte

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

Cobalah online!

(Hampir dua kali lipat jawaban Python: - \)

Mengambil input $args[0], melemparkannya sebagai [bigint], menyimpannya $n. Memasuki forloop. Setiap iterasi yang kita periksa apakah $njumlah dikonversi ke string kemudian ke char-array, ketika Group-Objectbersama-sama, memiliki .count -less daripada atau ekualifikasi untuk 9. Artinya, satu-satunya cara yang sama dengan 10 adalah jika setidaknya satu digit dari setiap angka 1234567890ada. Jika ya, kami keluar dari loop. Jika tidak, kami $n*=2dan lanjutkan. Setiap iterasi di dalam loop, kami hanya menambah $i. Ketika kita keluar dari loop, kita cukup mengeluarkan $i.

Perhatikan bahwa untuk input seperti di 1234567890mana setiap digit sudah diperhitungkan, ini tidak akan menghasilkan apa-apa, yang merupakan nilai falsey di PowerShell, dan setara dengan 0ketika dilemparkan sebagai [int]. Jika tidak OK, kita cukup meletakkan +di depan output $iuntuk secara eksplisit melemparkannya sebagai integer.

Menyimpan satu byte berkat Roland Heath.


Bisakah Anda menggunakan le9 bukan ne10? Saya tidak terbiasa dengan PowerShell, tapi itu mungkin menghemat satu byte.
Roland Heath

@RolandHeath Memang; panggilan yang bagus. Terima kasih!
AdmBorkBork



0

Perl, 43 +1 byte

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

Menggunakan -pbendera. Ini didasarkan pada solusi yang disediakan oleh Xcali di atas.


0

Cepat 4 , 111 byte

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

Catatan: Tidak akan berfungsi untuk x = 2, karena overflow.

Penjelasan - Input x pertama kali diketikkan ke string. Kemudian Set () menghapus karakter yang berulang. Kemudian disortir agar sesuai dengan hasilnya. Jika tidak cocok, x adalah ganda dan penghitung bertambah.


1
tidak wajan karena var 64 bit. Ada banyak jawaban lain dengan masalah yang sama.
Naresh


Jika Anda berpikir bahwa ini harus dibiarkan memunculkannya dengan OP. Ini mungkin praktik umum tetapi OP belum secara khusus mengizinkannya dan testcases tampaknya menyarankan Anda perlu mendukung 2.
Post Rock Garf Hunter

1
@ FunkyComputerMan sebenarnya, saya memang mengizinkan jawaban yang tidak dapat menangani angka di luar batas bahasa, tetapi Shaggy tampaknya telah menghapus komentar yang menanyakan hal itu. Jawaban ini baik-baik saja.
caird coinheringaahing

0

Rubi, 46 45 39 38 byte

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

Cobalah online!

Pembaruan:

  1. -1 dengan menggunakan def f n;alih-alih def f(n);.
  2. -6 dengan menggunakan …[9]bukan….size==10
  3. -1 dengan menghapus titik koma

0

Japt , 15 byte

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

Cobalah


Penjelasan

Input bilangan bulat implisit U.

LÆ    Ã

Buat array bilangan bulat dari 0ke 99dan melewati masing-masing melalui fungsi di mana Xelemen saat ini.

*2pX

Udikalikan dengan 2 dinaikkan menjadi kekuatan X.

b

Dapatkan indeks elemen pertama hingga kembali benar ketika melewati fungsi berikut.

ì_â

Membagi menjadi array angka dan menghapus duplikat.

Ê¥A

Dapatkan panjang array dan periksa kesetaraan dengan 10.


Alternatif, 15 byte

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

Cobalah


Penjelasan

Input bilangan bulat implisit U.

@            }a

Dimulai dengan 0, kembalikan angka pertama yang mengembalikan true ketika melewati fungsi berikut, dengan Xmenjadi angka saat ini.

*2pX)

Seperti di atas, kalikan Udengan 2 dengan kekuatan X.

ìâ

Membagi menjadi array angka, menghapus duplikat dan bergabung kembali ke integer.

Konversikan ke string, dapatkan panjangnya dan konversikan kembali ke integer.

¥A

Periksa kesetaraan dengan 10.


0

QBIC , 48 byte, nc

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

Ini seharusnya bekerja, secara teori. Namun, dalam praktiknya ini gagal karena QBasic memberikan angka sepuluh digit (setidaknya diperlukan untuk mendapatkan semua digit) ke notasi ilmiah ... Saya telah menandainya sebagai non-bersaing karena itu.

Penjelasan

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

Input disalin dari atas tumpukan (yang harus kosong); output didorong ke atas tumpukan.

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

Penjelasan

Kami menggunakan variabel array a, menyimpan 1 in a[d]jika digit dada, jika tidak kembali ke 0 di sana. Kami menggunakan ekstensi GNU ~untuk mendapatkan hasil bagi dan sisanya dalam satu perintah.

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

Sebagai bonus, ini akan bekerja dalam basis angka yang berubah-ubah (tidak hanya desimal): cukup atur radix input sesuai kebutuhan (konstanta 11dalam definisi fakan dibaca menggunakan basis nomor itu, sehingga secara otomatis benar).

Uji

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 byte

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

0

q / kdb + , 33 byte

Larutan:

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

Contoh:

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

Penjelasan:

Semua byte dalam kesetaraan, mungkin bisa menurunkan yang satu ini sedikit lebih jauh. Memanfaatkan scanketerangan 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

Catatan:

Jika kita turun ke kprompt maka kita dapat memiliki solusi 25 byte. Mengonversi nomor menjadi daftar karakter:

q)\
  #1_{x*2 1@&/($!10)in$$x}\[100]
51
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.