Menguraikan angka dengan bit-xor tanpa angka 0, 3, 7

20

Tantangan

Tulis fungsi atau program yang mengambil angka desimal positif, sebut saja A , dan hasilkan dua angka positif, B dan C , sehingga:

  • A == B bitxor C
  • B dan C tidak boleh mengandung digit 0, 3 atau 7 dalam representasi desimalnya.

Contohnya

>>> decompose(3)
1, 2
>>> decompose(7)
1, 6
>>> decompose(718)
121, 695
>>> decompose(99997)
2, 99999
>>> decompose(4294967296)
4294968218, 922
>>> decompose(5296080632396965608312971217160142474083606142654386510789497504098664630388377556711796340247136376)
6291484486961499292662848846261496489294168969458648464915998254691295448225881546425551225669515922,
1191982455588299219648819556299554251659915414942295896926425126251962564256469862862114191986258666

Karena dekomposisi tidak unik, fungsi / program Anda tidak perlu menampilkan hasil yang sama persis dengan contoh yang diberikan ini.

Aturan yang sangat rinci

  1. Pengajuan harus dalam bentuk fungsi atau program yang lengkap . importpernyataan memang diperhitungkan dalam skor akhir.

  2. Anda dapat mengasumsikan input A selalu mengandung setidaknya digit 0, 3 atau 7.

  3. Anda dapat menganggap bahwa dekomposisi selalu ada.

  4. Anda dapat menggunakan BigInt jika mereka adalah bagian dari perpustakaan standar bahasa, atau dapat diinstal melalui manajer paket de jure bahasa .

  5. Fungsinya harus cepat. Seharusnya tidak lebih dari 20 detik untuk berjalan di komputer yang cukup modern saat memasukkan nomor 100-digit, dan tidak lebih dari 2 detik saat memasukkan nomor 10-digit.

  6. Fungsi / program harus mendukung input hingga setidaknya 100 digit .

    • Jika fungsi / program hanya dapat mendukung bilangan bulat hingga N <100 digit, akan ada penalti sebesar + 10 × (100 / N - 1) byte ke skor akhir. Ini untuk mendorong pegolf untuk mendukung nomor yang lebih luas walaupun impor mungkin dilakukan secara verbal.
  7. Tidak ada batasan pada presentasi input / output selama mereka jelas dalam representasi desimal.

    • Fungsi ini dapat menginput dan mengeluarkan string / BigInts jika tipe integer bawaan tidak cukup.
    • Input mungkin berasal dari parameter fungsi, argumen baris perintah atau STDIN.
    • Fungsi dapat mengembalikan hasilnya, atau hanya mencetak hasilnya langsung ke STDOUT.
    • Namun, limpahan yang dimasukkan pada input / output tidak diizinkan.
    • Perkiraan jawaban tidak ditoleransi, input / output harus tepat.

Mencetak gol

Ini adalah . Solusi terpendek dalam byte menang.

Ada penalti jika program hanya dapat mendukung angka kurang dari 100 digit:

  • 64-bit integers (19 digit) = +42 byte
  • Bilangan bulat 63-bit (18 digit) = +45 byte
  • Bilangan bulat 53-bit (15 digit) = +56 byte
  • 31/32-bit integer (9 digit) = +101 byte
kennytm
sumber
2
Apakah Anda yakin penguraian seperti itu selalu memungkinkan? Bisakah Anda memberi saya bukti?
John Dvorak
Seseorang memblokir 1, 5, 9 dalam pertanyaan 95 Kutipan Film kemudian.
jimmy23013
3
100 digit? itu berarti Python langsung menang, karena itu adalah satu-satunya bahasa yang umum digunakan di sini yang mendukung integer presisi sewenang-wenang. Mengapa tidak 19 digit, yang cocok dengan bilangan bulat 64-tapi tidak ditandatangani? (2 ^ 64 = 18 446 744 073 709 551 616)
Level River St.
5
@steveverrill Mathematica ... GolfScript ... CJam ...
Martin Ender
1
Dan Jawa (harus mengatakan itu)
Ypnypn

Jawaban:

2

CJam, 70 byte

ri:Q{;Qmr_Q^`1$`+730`&}g_Q^p

Cobalah online.

Pilih bilangan bulat secara acak hingga menemukan kecocokan. Ini hampir tidak sesuai dengan batas 20 detik untuk integer 64-bit (menggunakan interpreter Java), jadi saya telah menambahkan 42 ke jumlah byte yang sebenarnya.

Contoh dijalankan

$ cjam t <<< 7777777777; echo
2695665494
6161166119
Dennis
sumber
10

Common Lisp, 240 224 183 173 169 byte

Common Lisp agak verbose untuk bermain golf. Namun, ini menguraikan angka 100 digit dalam waktu kurang dari satu detik, dan bilangan bulat 200 digit dalam waktu kurang dari sepuluh detik, jadi tidak perlu penalti. Algoritma bersifat deterministik.

(defun s(z)(and #1=(some(lambda(q)(position q(format()"~a"z)))"037")(+ z(floor z(expt 10 #1#)))))
(defun d(x)(do((y x(or(s y)(s #3=(logxor x y))(return`(,y,#3#)))))(())))

Umpan garis antara fungsi-fungsi ini hanya untuk keperluan tipografi. Uji coba dengan input referensi 100 digit:

(time (d 5296080632396965608312971217160142474083606142654386510789497504098664630388377556711796340247136376))
took 677,000 microseconds (0.677000 seconds) to run.
      20,989 microseconds (0.020989 seconds, 3.10%) of which was spent in GC.
During that period, and with 8 available CPU cores,
     671,875 microseconds (0.671875 seconds) were spent in user mode
           0 microseconds (0.000000 seconds) were spent in system mode
 54,221,104 bytes of memory allocated.
(1864921261592819619661568919418981552559955289196969112566252282429216186594265918444566258544614425
 5891958562486995519825158818455999516899524658151445485616155916296966645869599949958954491929662561)

Sebagai bonus, saya menyertakan versi kode yang secara bertahap membangun solusi dari atas ke bawah. Ia dapat mengatur angka 1000 digit dalam waktu kurang dari sepuluh detik, tetapi tidak dapat bersaing dalam golf karena kode tambahan.

(defun decompose (x)
  (flet ((s (z)
           (mapcan #'(lambda (c) (and #1=(position c #2=(format () "~a" z))
                                 (list (- (length #2#) #1# 1))))
                   '(#\0 #\3 #\7))))
    (do ((y x (let ((p (nconc (s y) (s #3=(logxor x y)))))
                (or p (return`(,y,#3#)))
                (+ y (expt 10 (apply #'max p))))))
        (nil))))

* (time (decompose (parse-integer (make-string 1000 :initial-element #\7))))
took 9,226,000 microseconds (9.226000 seconds) to run.
        90,966 microseconds (0.090966 seconds, 0.99%) of which was spent in GC.
During that period, and with 8 available CPU cores,
     9,234,375 microseconds (9.234375 seconds) were spent in user mode
             0 microseconds (0.000000 seconds) were spent in system mode
 487,434,560 bytes of memory allocated.
(8889898889152488921298888992819221914229899249999918899888899888888889999989141219898898888988988898888888888899142442899924898918898898988988895189988898888924192198992454114198911989191888889898888918888988988998888891421118891899122898888998989898888898988898888999988918888898889189918889888888899888989219188898998888988892119889198888988888894888912188898989952999888888888898899998988898889228918998949999998898898991141888898999988912121292118899889998989899999892889941898888911888898889118998898888911889889888891452888998889288921141888888942189888899988891918889118888888888989892198899199914111188988889421111188889118888918989988912989999998989891119888898888888892621229888988888999619888952462219889189899998899888889989898891118989218888888898962988891188899888888888999888888888888888888888891269188921288888888998898899214191188888888898992188998898889919888889989889899988892115549998888898889218899988998911898989199918898918988898888891889888989119899888889888998918889112189998
 4184469818464841952189561886965821566229261221619858498284264289194458622668559698924621446851546256444641488616184155821914881485164244662156846141894655485889656891849662551896595944656451462198891289692696856414192264846811616261884188919426294584158925218559295881946496911489245664261126565546419851585441144861859822815144162828551969425529258169849412525611662488849586554989254181228254465226521648916188265491499166186964881248156451994924294646681548996645996894665198811511522424996844864211629888924642289925565591484541149414914699289441561496451494562955652129199261462268846144518142486845251946444998812988291119592418684842524648484689261441456645518518812265495165189812912919529151991611962525419626921619824496626511954895189658691229655648659252448158451924925658586522262194585891859285841914968868466462442488528641466655911199816288496111884591648442984864269495264612518852292965985888414945855422266658614684922884216851481646226111486498155591649619266595911992489425412191)
* (apply #'logxor *)
7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777
jlahd
sumber
2

Python 2, 103 + 42 = 145 byte

Python secara alami mendukung bigints, tetapi program ini jauh melebihi 20 detik untuk angka 100 digit. Namun, itu terurai integer 64-bit dalam waktu sekitar 2 detik.

from random import *
def d(a):
 b=c=0
 while set(`b`+`c`)&set('037'):
    b=randint(1,a);c=a^b
 return b,c
Remy
sumber
1
Gagasan cerdas menggunakan keacakan. Jika Anda mendefinisikan suatu fungsi, Anda tidak perlu whileloop untuk terus mencoba nilai acak - Anda bisa memanggil fungsi itu lagi. Tanpa perlu struktur pengendalian, maka Anda dapat runtuh fungsi ke lambdadan ternary a: from random import* d=lambda a,b=0:set(`b`+`a^b`)&set(\'037\')and d(a,randint(1,a))or(b,a^b). Meskipun Anda mungkin lebih baik tidak menggunakan fungsi.
xnor
Saya dianggap rekursi, tetapi menyebabkan stack overflow untuk jumlah besar (bahkan hanya 11 digit).
Remy
1

Python 3 (132 byte)

(Ini hanya untuk merangsang solusi yang lebih baik. Ini adalah solusi saya ketika menyelesaikan masalah asli dalam film ASCII.)

def d(a):
 l=len(str(a));s=int('1'*l);u=10**(l-1)
 while u:
  while set(str(s)+str((a^s)//u))&set('037'):s+=u
  u//=10
 print(s,a^s)

Meskipun perilaku bitwise xor dalam sistem desimal cukup rumit, ada satu pengamatan utama: memodifikasi digit rendah tidak akan mempengaruhi digit tinggi . Oleh karena itu, kita dapat bekerja dari atas ke bawah: cobalah untuk membuat digit atas bebas dari 0, 3, 7, dan kemudian bekerja pada digit berikutnya, hingga seluruh angka dikerjakan. Ini memungkinkan kita untuk berjalan dalam waktu linier, kemudian memproses angka seribu digit dapat diselesaikan dalam waktu kurang dari 1 detik. (Solusi Common Lisp juga menggunakan teknik yang sama saya percaya.)

kennytm
sumber
Tetapi memperbaiki digit rendah dapat memengaruhi digit tinggi. Misalnya 997^8 == 1005,. Saya pikir ada kernel ide di sini, tetapi tidak jelas.
Keith Randall
@KeithRandall: Ya itu seperti 999 ... 999 +1, tetapi, diberi pilihan {1,2,4,5,6,8,9}, akan ada beberapa dari mereka yang tidak akan mempengaruhi angka tinggi. (mis 997^2 == 999.). whileLingkaran dalam melakukan kelelahan untuk menemukan pilihan yang membuat angka tinggi tetap valid.
kennytm
benar, tapi kemudian tidak jelas (bagi saya, setidaknya) bahwa pasti ada angka yang akan berfungsi.
Keith Randall