0, 3, 7 basamakları olmadan bit-xor ile bir sayıyı ayrıştırın


20

Meydan okuma

Pozitif ondalık sayı alan bir işlev veya program yazın, A olarak adlandırın ve şu şekilde iki pozitif sayı, B ve C çıktısını verin :

  • A == B bitx veya C
  • B ve C , ondalık gösteriminde 0, 3 veya 7 rakamlarından hiçbirini içermemelidir.

Örnekler

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

Ayrışma benzersiz olmadığından, işlevinizin / programınızın bu örneklerle tam olarak aynı sonuçları vermesi gerekmez.

Çok detaylı kurallar

  1. Başvurular tam bir fonksiyon veya program şeklinde olmalıdır . importifadeleri do nihai puanınızı.

  2. A girişinin her zaman en az 0, 3 veya 7 basamak içerdiğini varsayabilirsiniz .

  3. Her zaman bir ayrışma olduğunu varsayabilirsiniz.

  4. Dilin standart kitaplıklarının bir parçasıysa veya dilin de jure paket yöneticisi aracılığıyla yüklenebilirse BigInt'i kullanabilirsiniz .

  5. İşlev hızlı olmalıdır. Bu en fazla almalı 20 saniyede 10 haneli bir sayı ile beslendiklerinde fazla 2 saniyeden daha 100 haneli bir numara beslenen ve ne zaman makul modern bilgisayar üzerinde çalışacak.

  6. İşlev / program en az 100 rakama kadar girişi desteklemelidir .

    • İşlev / program yalnızca N <100 basamağa kadar olan tam sayıları destekleyebiliyorsa , son skora + 10 × (100 / N - 1) baytlık bir ceza verilir . Bu, golfçüleri içe aktarma ayrıntılı olsa bile daha geniş bir sayı aralığını desteklemeye teşvik etmektir.
  7. Orada sunu üzerinde herhangi bir kısıtlama yeter ki ondalık temsil olduğun gibi, girdi / çıktılar.

    • Yerleşik tamsayı türleri yeterli değilse, işlev dizeleri / BigInts'i girip çıkarabilir.
    • Giriş, fonksiyon parametresinden, komut satırı argümanından veya STDIN'den gelebilir.
    • İşlev sonucu döndürebilir veya sonucu doğrudan STDOUT'a yazdırabilir.
    • Ancak, giriş / çıkışlarda imzalı taşmaya izin verilmez.
    • Yaklaşık cevaplar tolere edilmez, giriş / çıkışların kesin olması gerekir.

puanlama

Bu bir . Bayt kazanmada en kısa çözüm.

Program yalnızca 100 basamaktan küçük sayıları destekleyebiliyorsa bir ceza vardır:

  • 64 bit tamsayılar (19 basamaklı) = +42 bayt
  • 63 bit tamsayılar (18 basamaklı) = +45 bayt
  • 53 bit tamsayılar (15 basamaklı) = +56 bayt
  • 31/32 bit tamsayılar (9 basamaklı) = +101 bayt

2
Böyle bir ayrışmanın her zaman mümkün olduğundan emin misiniz? Bana bir kanıt çizebilir misin?
John Dvorak

Birisi 95 Film Alıntıları sorusundaki 1, 5, 9'u engeller .
jimmy23013

3
100 hane? Bu, keyfi hassasiyet tam sayılarını destekleyen tek yaygın dil olduğu için Python'un hemen kazandığı anlamına gelir. Neden 64 ama işaretsiz bir tam sayıya uyan 19 basamak değil? (2 ^ 64 = 18446 744 073709 551616)
Level River St

5
@steveverrill Mathematica ... GolfScript ... CJam ...
Martin Ender

1
Ve Java (bunu söylemek zorundaydı)
Ypnypn

Yanıtlar:


2

CJam, 70 bayt

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

Çevrimiçi deneyin.

Bir eşleşme bulana kadar tam sayıları rastgele seçer. Bu, 64 bit tamsayılar için 20 saniyelik sınırlamaya neredeyse hiç uymuyor (Java yorumlayıcısını kullanarak), bu yüzden gerçek bayt sayısına 42 ekledim.

Örnek çalışma

$ cjam t <<< 7777777777; echo
2695665494
6161166119

10

Ortak Lisp 240 224 183 173 169 bayt

Ortak Lisp golf için biraz ayrıntılı. Ancak, bu bir saniyenin altında 100 basamaklı sayıları ve on saniyeden kısa sürede 200 basamaklı tam sayıları ayrıştırır, bu nedenle cezaya gerek yoktur. Algoritma deterministiktir.

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

İşlevler arasındaki satır besleme yalnızca tipografik amaçlıdır. 100 basamaklı referans girişi ile test çalıştırması:

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

Bonus olarak, aşamalı olarak çözümü yukarıdan aşağıya oluşturan kodun bir sürümünü ekliyorum. 1000 basamaklı bir sayıyı on saniyeden daha kısa sürede yönetebilir, ancak ek kod nedeniyle golfte rekabet edemez.

(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

2

Python 2,103 + 42 = 145 bayt

Python yerel olarak bigint'leri destekler, ancak bu program 100 haneli bir sayı için 20 saniyeyi aşar. Ancak, yaklaşık 2 saniyede 64 bit tamsayıları ayrıştırır.

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

1
Rasgelelik kullanarak akıllı fikir. Bir işlev tanımlıyorsanız, whilerastgele değerleri denemeye devam etmek için bir döngüye ihtiyacınız yoktur - işlevi yeniden çağırabilirsiniz. Kontrol yapıya gerek olmadan, daha sonra bir işlevi daraltabilirsiniz lambdave üçlü: from random import* d=lambda a,b=0:set(`b`+`a^b`)&set(\'037\')and d(a,randint(1,a))or(b,a^b). Bir işlevi kullanmamanız daha iyi olabilir.
xnor

Özyinelemeyi düşündüm, ancak çok sayıda (hatta 11 basamaklı) için bir yığın taşmasına neden olur.
Remy

1

Python 3 (132 bayt)

(Bu sadece daha iyi çözümleri teşvik etmek içindir. Bu, ASCII filmindeki orijinal sorunu çözerken benim çözümüm.)

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)

Ondalık sistemdeki bitsel xor davranışı oldukça karmaşık olmasına rağmen, büyük bir gözlem vardır: düşük basamakların değiştirilmesi yüksek basamakları etkilemez . Bu nedenle, yukarıdan aşağıya çalışabiliriz: üst basamakları 0, 3, 7'den kurtarmaya çalışın ve ardından tam sayı çalışana kadar bir sonraki basamakta çalışın. Bu, lineer zamanda çalışmamızı sağlar, ardından bin haneli bir sayıyı işlemek 1 saniyenin altında tamamlanabilir. (Common Lisp çözümü de inandığım aynı tekniği kullanıyor.)


Ama düşük basamak sabitleme olabilir yüksek rakamları etkiler. Örneğin 997^8 == 1005,. Bence burada bir fikir çekirdeği var, ama belli değil.
Keith Randall

@KeithRandall: Evet, tıpkı 999… 999 + 1 gibi, ancak seçim göz önüne alındığında {1,2,4,5,6,8,9}, yüksek basamakları etkilemeyecek bazıları var. (örneğin 997^2 == 999). İç whiledöngü, yüksek rakamları geçerli tutan seçimi bulmak için bitkinliği yapar.
kennytm

doğru, ama o zaman (en azından benim için) kesinlikle işe yarayacak bir rakam olduğu açık değil.
Keith Randall
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.