数字0、3、7のないビットxorで数値を分解します


20

チャレンジ

正の10進数をとる関数またはプログラムを作成し、それをAと呼び、次のような2つの正の数値BCを出力します。

  • A == B bitxor C
  • BおよびCには、10進表現に数字0、3、または7を含めることはできません。

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

分解は一意ではないため、関数/プログラムはこれらの例とまったく同じ結果を出力する必要はありません。

非常に詳細なルール

  1. 提出は完全な機能またはプログラムの形であるべきです。importステートメント最終スコアにカウントされます。

  2. 入力Aには常に少なくとも0、3、または7の数字が含まれると仮定できます。

  3. 分解が常に存在すると仮定できます。

  4. BigIntは、言語の標準ライブラリの一部であるか、言語のde jureパッケージマネージャーを介してインストールできる場合に使用できます。

  5. 関数は高速でなければなりません。100桁の数字を入力した場合、最新のコンピューターで実行するのに20秒以内、10桁の数字を入力した場合、2秒以内です。

  6. 関数/プログラムは、少なくとも100桁までの入力をサポートする必要があります

    • 関数/プログラムがN <100桁までの整数のみをサポートできる場合、最終スコアに対して+ 10×(100 / N-1)バイトのペナルティがあります。これは、インポートが冗長である場合でも、ゴルファーがより広い範囲の数字をサポートすることを奨励するためです。
  7. 入出力が明確に10進表記である限り、入出力の表示制限はありません

    • 組み込み整数型では不十分な場合、関数は文字列/ BigIntsを入出力できます。
    • 入力は、関数パラメーター、コマンドライン引数、またはSTDINから取得できます。
    • 関数は結果を返すか、単に結果を直接STDOUTに出力します。
    • ただし、入出力の符号付きオーバーフローは許可されていません。
    • おおよその回答は許容されません。入力/出力は正確でなければなりません。

得点

これはです。バイト単位の最短ソリューションが勝ちます。

プログラムが100桁未満の数字のみをサポートできる場合、ペナルティがあります。

  • 64ビット整数(19桁)= +42バイト
  • 63ビット整数(18桁)= +45バイト
  • 53ビット整数(15桁)= +56バイト
  • 31/32ビット整数(9桁)= +101バイト

2
そのような分解は常に可能であると確信していますか?証拠をスケッチしてもらえますか?
ジョン・ドヴォルザーク

誰かが95の映画の引用の質問で 1、5、9をブロックします。
jimmy23013 14年

3
100桁?Pythonは、ここで任意の精度の整数をサポートする唯一の一般的に使用される言語であるため、すぐに勝ちます。64桁の符号なし整数に収まる19桁はなぜですか?(2 ^ 64 = 18 446 744 073 709 551 616)
レベル・リバーセント

5
@steveverrill Mathematicaの... GolfScript ... CJam ...
マーティン・エンダー

1
そして、Javaは、(それを言っていた)
Ypnypn

回答:


2

CJam、70バイト

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

オンラインでお試しください。

一致が見つかるまでランダムに整数を選択します。これは(Javaインタープリターを使用して)64ビット整数の20秒の制限にほとんど準拠していないため、実際のバイトカウントに42を追加しました。

実行例

$ cjam t <<< 7777777777; echo
2695665494
6161166119

10

Common Lisp、240 224 183 173 169バイト

Common Lispは、ゴルフでは少し冗長です。ただし、これは100桁の数字を1秒未満で分解し、200桁の整数を10秒未満で分解するため、ペナルティーは必要ありません。アルゴリズムは決定論的です。

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

関数間の改行は、活版印刷のみを目的としています。100桁の参照入力を使用したテスト実行:

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

ボーナスとして、トップダウンでソリューションを段階的にビルドするコードのバージョンを含めています。10数秒で1000桁の数字を管理できますが、追加のコードのためにゴルフに参加できません。

(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バイト

Pythonはネイティブでbigintをサポートしていますが、このプログラムは100桁の数値で20秒をはるかに超えています。ただし、約2秒で64ビット整数を分解します。

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
ランダムネスを使用した賢いアイデア。関数を定義している場合、whileランダムな値を試行し続けるためのループは不要です。関数を再度呼び出すだけで済みます。制御構造を必要とせずに、関数をlambda3つに折りたたむことができますfrom random import* d=lambda a,b=0:set(`b`+`a^b`)&set(\'037\')and d(a,randint(1,a))or(b,a^b)。ただし、関数を使用しない方が良いかもしれません。
xnor 14年

再帰を検討しましたが、大きな数値(わずか11桁でも)でスタックオーバーフローが発生します。
レミー14年

1

Python 3(132バイト)

(これは、より良いソリューションを刺激するためです。これは、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)

10進数システムでのビット単位のxorの動作はかなり複雑ですが、1つの大きな観測があります下位桁を変更しても上位桁には影響しません。したがって、トップダウンで作業することができます。上位の数字を0、3、7から解放し、次の数字を処理して、全体の数字を計算します。これにより、線形時間で実行でき、1000桁の数字の処理は1秒未満で完了します。(Common Lispソリューションも私が信じているのと同じテクニックを使用しています。)


ただし、下位の数字を修正すると上位の数字に影響する場合があります。たとえば、997^8 == 1005。ここにはアイデアの核心があると思うが、それは明らかではない。
キースランドール14

@KeithRandall:はい、それは999…999 + 1のようなものですが、を選択した{1,2,4,5,6,8,9}場合、上位桁に影響を与えないものがいくつかあります。(例997^2 == 999)。内側のwhileループは、上位桁を有効に保つ選択肢を見つけるために使い果たします。
ケニー14

正しいのですが、間違いなく機能する数字があることは明らかです(少なくとも、私には)。
キースランドール14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.