Faktor Anagram

19

Pada episode terbaru QI , 5 kelipatan pertama dari 142857 digambarkan sebagai anagram dari nomor aslinya. Tentu saja, siapa pun yang memiliki lebih dari pengetahuan yang lewat tentang angka itu akan tahu bahwa angka-angka itu sebenarnya siklik, bukan hanya anagram. Tapi itu membuat saya berpikir.

Silakan tulis sebuah program atau fungsi yang menampilkan semua angka dari enam atau lebih sedikit digit yang memiliki faktor tepat yang merupakan anagram itu sendiri. Daftar harus dimulai dengan angka-angka berikut:

3105    (divisible by 1035)
7128    (divisible by 1782)
7425    (divisible by 2475)
8316    (divisible by 1386)
8712    (divisible by 2178)
9513    (divisible by 1359)
9801    (divisible by 1089)

Jika Anda suka, Anda dapat menemukan angka yang memiliki anagram yang merupakan faktor yang tepat dari angka tersebut, tetapi berhati-hatilah untuk tidak memasukkan angka nol di depan dari anagram Anda.

Ini adalah kode golf, jadi kode terpendek dalam byte yang tidak memecah celah standar menang.

Neil
sumber
Jika diberikan waktu yang cukup, dapatkah program kami mengeluarkan angka dengan lebih dari 6 digit?
Biru
1
Bisakah Anda memposting daftar?
xnor
@muddyfish Ya, itu bisa diterima, asalkan tidak menghilangkan angka atau menghasilkan angka yang salah saat berjalan.
Neil
@ xnor Saya sebenarnya belum repot-repot menghitung seluruh daftar, meskipun saya tidak mengharapkan ada perselisihan tentang itu.
Neil
1
Saya membuat pastebin dari output saya (semoga benar).
Greg Martin

Jawaban:

6

Mathematica (lingkungan REPL), 75 74 byte

Terima kasih kepada ngenisis untuk memperketat byte ini!

Select[Range[10!],Most@#~MemberQ~Last@#&[Sort/@IntegerDigits@Divisors@#]&]

Sort/@IntegerDigits@Divisors@#menghasilkan daftar angka yang diurutkan untuk setiap pembagi argumennya; nomor input itu sendiri adalah pembagi, jadi daftar digit yang diurutkan adalah yang terakhir. Most@#~MemberQ~Lastmendeteksi apakah daftar angka yang terakhir disortir juga muncul dalam daftar sebelum elemen terakhir. Dan Select[Range[10!],...]hanya mempertahankan bilangan bulat tersebut hingga 3.628.800 yang lulus tes ini (yang terikat dipilih karena itu satu byte lebih pendek dari 10 6 ). Ini berjalan sekitar 5 menit di komputer saya, menghasilkan daftar 494 angka, yang terbesar adalah 3.427.191; ada 362 angka hingga 10 6 , yang terbesar adalah 989.901.

Greg Martin
sumber
Ya, itu tidak terlalu aneh: 857142 dan 571428 adalah dua angka keduanya dengan dua diagram pembagi yang jelas.
Neil
Sebenarnya, 857142 memiliki tiga anagram pembagi yang tepat, bukan?
Neil
Sepertinya kamu benar!
Greg Martin
Anda dapat menyimpan byte dengan menggunakan IntegerDigits@Divisors@#.
ngenisis
3

Jelly , 12 byte

ÆḌṢ€ċṢ
ȷ6ÇÐf

Cobalah online! (menggunakan lima digit atau lebih sedikit karena batas waktu TIO)

Verifikasi

$ time jelly eun 'ÆḌṢ€ċṢ¶ȷ6ÇÐf'
[3105, 7128, 7425, 8316, 8712, 9513, 9801, 30105, 31050, 37125, 42741, 44172, 67128, 70416, 71208, 71253, 71280, 71328, 71928, 72108, 72441, 74142, 74250, 74628, 74925, 78912, 79128, 80712, 81816, 82755, 83160, 83181, 83916, 84510, 85725, 86712, 87120, 87132, 87192, 87912, 89154, 90321, 90801, 91152, 91203, 93513, 94041, 94143, 95130, 95193, 95613, 95832, 98010, 98091, 98901, 251748, 257148, 285174, 285714, 300105, 301050, 307125, 310284, 310500, 321705, 341172, 342711, 370521, 371142, 371250, 371628, 371925, 372411, 384102, 403515, 405135, 410256, 411372, 411723, 415368, 415380, 415638, 419076, 419580, 420741, 421056, 423711, 425016, 427113, 427410, 427491, 428571, 430515, 431379, 431568, 435105, 436158, 441072, 441720, 449172, 451035, 451305, 458112, 461538, 463158, 471852, 475281, 501624, 502416, 504216, 512208, 512820, 517428, 517482, 517725, 525771, 527175, 561024, 562104, 568971, 571428, 571482, 581124, 589761, 615384, 619584, 620379, 620568, 623079, 625128, 641088, 667128, 670416, 671208, 671280, 671328, 671928, 672108, 678912, 679128, 681072, 691872, 692037, 692307, 704016, 704136, 704160, 704196, 705213, 705321, 706416, 711342, 711423, 712008, 712080, 712503, 712530, 712800, 713208, 713280, 713328, 713748, 714285, 716283, 717948, 719208, 719253, 719280, 719328, 719928, 720108, 720441, 721068, 721080, 721308, 721602, 723411, 724113, 724410, 724491, 728244, 730812, 731892, 732108, 741042, 741285, 741420, 742284, 742500, 744822, 746280, 746928, 749142, 749250, 749628, 749925, 753081, 754188, 755271, 760212, 761082, 761238, 761904, 771525, 772551, 779148, 783111, 786912, 789120, 789132, 789192, 789312, 790416, 791208, 791280, 791328, 791928, 792108, 798912, 799128, 800712, 806712, 807120, 807132, 807192, 807912, 814752, 816816, 818160, 818916, 820512, 822744, 823716, 824472, 825174, 825714, 827550, 827658, 827955, 829467, 830412, 831117, 831600, 831762, 831810, 831831, 839160, 839181, 839916, 840510, 841023, 841104, 843102, 845100, 845910, 847422, 851148, 851220, 851742, 852471, 857142, 857250, 857628, 857925, 862512, 862758, 862947, 865728, 866712, 867120, 867132, 867192, 867912, 871200, 871320, 871332, 871425, 871920, 871932, 871992, 874125, 879120, 879132, 879192, 879912, 888216, 891054, 891540, 891594, 891723, 892755, 894510, 895725, 899154, 900801, 901152, 903021, 903210, 903231, 904041, 908010, 908091, 908901, 909321, 910203, 911043, 911358, 911520, 911736, 911952, 912030, 912093, 912303, 916083, 920241, 920376, 923076, 923580, 925113, 925614, 930321, 931176, 931203, 933513, 934143, 935130, 935193, 935613, 935832, 940410, 940491, 941430, 941493, 941652, 943137, 943173, 951300, 951588, 951930, 951993, 952380, 956130, 956193, 956613, 958032, 958320, 958332, 958392, 958632, 958716, 959832, 960741, 962037, 962307, 970137, 971028, 980100, 980910, 980991, 989010, 989091, 989901]

real    2m10.819s
user    2m10.683s
sys     0m0.192s

Bagaimana itu bekerja

ȷ6ÇÐf   Main link. No arguments.

ȷ6      Yield 1e6 = 1,000,000.
  ÇÐf   Filter; keep numbers in [1, ..., 1e6] for which the helper link returns
        a truthy value.


ÆḌṢ€ċṢ  Helper link. Argument: n

ÆḌ      Compute all proper divisors of n.
  Ṣ€    Sort each proper divisor's digits.
     Ṣ  Sort n's digits.
   ċ    Count the occurrences of the result to the right in the result to the left.
Dennis
sumber
1
Karena komentar ini, Anda dapat melakukan lebih lambat ÆḌṢ€ċṢµȷ#untuk 10. Butuh waktu ~ 27 menit untuk berjalan pada inti i7 (bukan pada unix, tidak baik time); hasil terbesar adalah 6671928.
Jonathan Allan
Saya mulai berpikir Anda memodifikasi Jelly berdasarkan per pertanyaan 😏
Albert Renshaw
3

Brachylog , 12 byte

ℕf{k∋p.!}?ẉ⊥

Cobalah online!

Ini mungkin kehabisan waktu sebelum mencetak apa pun (dan jika tidak, ia hanya akan mencetak 3105).

Penjelasan

Ini mencetak angka-angka itu tanpa batas, karena penulis mengatakan itu dapat diterima bahwa program akan mencetak angka lebih besar dari 6 digit.

Ini terlalu lambat; Anda dapat menggunakan program ini (dan mengubahnya 8300dengan yang lain N) untuk mulai mencetak dari angka yang jauh lebih besar dari N.

ℕ               Natural number: The Input is a natural number
 f              Factors: compute the factors of the Input
  {     }?      Call a predicate with the main Input as its output and the factors as Input
   k            Knife: remove the last factor(which is the Input itself)
    ∋           In: take one of those factors
     p.         Permute: the Output is a permutation of that factor
       !        Cut: ignore other possible permutations
         ?ẉ     Writeln: write the Input to STDOUT, followed by a line break
           ⊥    False: backtrack to try another value for the Input

Seperti @ ais523 tunjukkan, kita perlu potongan untuk menghindari mencetak angka beberapa kali jika beberapa faktornya adalah permutasi darinya.

Fatalisasi
sumber
Saya memiliki jawaban yang sangat mirip yang disimpan sebagai konsep. Sayangnya, saya tidak berpikir itu berfungsi karena akan mencetak angka seperti 857142 lebih dari sekali, dan penulis mengatakan itu tidak diizinkan. Saya pikir program perlu dipotong di suatu tempat, kemungkinan menambah tiga karakter.
Menambahkan 4 karakter sebenarnya ... terima kasih, lupakan itu.
Fatalkan
3

JavaScript (ES6), 10396 94 byte

Fungsi anonim yang mengembalikan array bilangan bulat yang cocok.

_=>[...Array(1e6).keys(F=i=>[...i+''].sort()+0)].filter(n=>n*(R=i=>F(n/i--)==F(n)||R(i)%i)(9))

Diformat dan dikomentari

_ =>                                // main function, takes no input
  [...Array(1e6).keys(              // define an array of 1,000,000 entries
    F = i => [...i + ''].sort() + 0 // define F: function used to normalize a string by
  )]                                // sorting its characters
  .filter(n =>                      // for each entry in the array:
    n * (                           // force falsy result for n = 0
      R = i =>                      // define R: recursive function used to test if
        F(n / i--) == F(n) ||       // n/i is an anagram of n, with i in [1 … 9]
        R(i) % i                    // F(n/1) == F(n) is always true, which allows to stop
    )                               // the recursion; but we need '%i' to ignore this result
    (9)                             // start recursion with i = 9
  )                                 //

Statistik pembagi

Untuk bilangan bulat 6 digit, masing-masing rasio dari 2ke 9antara bilangan bulat yang cocok ndan anagram yang ditemui setidaknya sekali. Tetapi beberapa dari mereka muncul hanya beberapa kali:

 divisor | occurrences | first occurrence
---------+-------------+---------------------
    2    |    12       | 251748 / 2 = 125874
    3    |    118      | 3105   / 3 = 1035
    4    |    120      | 7128   / 4 = 1782
    5    |    4        | 714285 / 5 = 142857
    6    |    34       | 8316   / 6 = 1386
    7    |    49       | 9513   / 7 = 1359
    8    |    2        | 911736 / 8 = 113967
    9    |    23       | 9801   / 9 = 1089

Uji

Tes di bawah ini terbatas pada rentang [1 ... 39999]sehingga tidak perlu terlalu banyak waktu untuk menyelesaikannya.

Arnauld
sumber
Jauh lebih cepat versi, tapi agak lama: _=>[...Array(1e6).keys()].filter(n=>n&&![...Array(9)].every(_=>n%++i||(F=i=>[...i+''].sort()+'')(n/i)!=F(n),i=1)).
Neil
@Neil Saran Anda menginspirasi saya versi terbaru yang jauh lebih cepat dan 1 byte lebih pendek. Sayangnya, semua pembagi dari 2ke 9diperlukan ( 8digunakan hanya dua kali untuk 911736dan 931176).
Arnauld
2

Perl 6 , 59 byte

{grep {grep .comb.Bag===*.comb.Bag,grep $_%%*,2..^$_}

Solusi brute force yang sangat lambat.

Ini mengembalikan urutan malas, jadi saya bisa memeriksa beberapa hasil pertama, tetapi tidak akan mencapai semua hasil dalam waktu yang wajar. (Haruskah saya menandainya sebagai non-bersaing?)

seseorang
sumber
2

Pure Bash , 128 126 122 121 120 byte

for((;n<6**8;)){
c=0
for((j=++n;j;j/=10)){((c+=8**(j%10)));}
for k in ${a[c]};{((n%k))||{ echo $n;break;};}
a[c]+=\ $n
}

Cobalah online!

(Program ini cukup cepat - hanya butuh 14 menit untuk menjalankan semua angka 6 digit di MacBook saya. Sayangnya TIO habis karena memaksakan batas waktu berjalan 1 menit, yang hanya cukup waktu untuk melewati 5 digit angka atau lebih.)

Utilitas Bash + Unix, 117 byte

for n in {1..999999}
{
c=$(bc<<<0`sed 's/\(.\)/+8^\1/g'<<<$n`)
for k in ${a[c]};{((n%k))||echo $n;}
a[c]+=\ $n
}|uniq

Ini lebih pendek dari versi bash murni, tetapi sedikit lebih lambat, mungkin karena sebagian besar forking terjadi.

Mitchell Spector
sumber
1

05AB1E , 15 byte

[¼¾œJv¾Ñ¨Dyåi¾,

Penjelasan:

[               # Start of infinite loop
 ¼              # Increase counter_variable by 1
  ¾œJv          # Loop through all the permutations of counter_variable
      ¾Ñ¨Dyå    # Check if a divisor of counter_variable is a permutation of counter_variable
            i¾, # If so, print counter_variable

Cobalah online! (ini tidak akan berhasil, itu akan habis)

Okx
sumber
1

Japt , 23 byte

L³o f_ì á ¤fg mì f!vZ l

Cobalah online! Perhatikan bahwa kode tertaut hanya menghitung hingga 1e4 karena 1e6 kali keluar pada TIO.

Oliver
sumber
0

Python 2, 98 byte

s=sorted;print filter(None,[[x for i in range(x)if s(`x`)==s(`i`)and x%i<1]for x in range(10**6)])
Trelzevir
sumber
Bukankah seharusnya begitu 10**6?
Neil
Ya terima kasih.
Trelzevir
1
Saya pikir x%i==0bisa saja x%i<1.
Yytsi
0

05AB1E , 12 10 byte

Waktu habis pada TIO karena loop tak terbatas.
Menyimpan 2 byte karena kami dapat menampilkan lebih dari 6 digit angka menurut komentar OP.

[NѨ€{N{å–

Cobalah online!

Penjelasan

[            # infinite loop with iteration index N
 NÑ          # get a list of all divisors of N
   ¨         # remove N from that list
    €{       # sort each entry in the list of divisors
      N{     # sort N
        å–   # output N if N is in the list
Emigna
sumber
0

Batch, 263 byte

@echo off
set e=exit/b
for /l %%n in (1,1,999999)do call:n %%n
%e%
:n
call:c %1 1 0
for /l %%f in (2,1,9)do call:c %1 %%f %c%&&echo %1&&%e%
%e%
:c
set/ar=%1%%%2,d=%1/%2,c=-%3
if %r% gtr 0 %e%1
:l
set/ac+=1^<^<d%%10*3,d/=10
if %d% gtr 0 goto l
%e%%c%

Lambat. Seperti dalam, membutuhkan waktu lebih dari satu hari untuk menyelesaikan PC saya. Penjelasan: csubrutin membagi dua argumen pertamanya. Jika sisanya adalah nol, itu kemudian menghitung hash hasil dengan menghitung jumlah dari kekuatan ke-8 dari 8 untuk setiap digit. Fungsi hash ini, dicuri dari jawaban bash, hanya bertabrakan pada anagram. (Ini akan bekerja untuk angka tujuh digit tapi saya tidak punya dua minggu.) Argumen ketiga dikurangi, dan subrutin keluar dengan hasil yang benar jika ini nol. The nsubroutine panggilan csubroutine sekali untuk menghitung hash, maka delapan kali untuk membandingkan hash; jika menemukan tabrakan, ia mencetak ndan keluar subrutin awal.

Neil
sumber