ผลรวมหรือความแตกต่างของสองพลังของทั้งสอง


27

ความท้าทายของคุณหากคุณเลือกที่จะรับมันคือได้รับจำนวนเต็มK >= 1หาจำนวนที่ไม่เป็นลบAและB เช่นนั้นอย่างน้อยหนึ่งในสองเงื่อนไขต่อไปนี้:

  1. K = 2^A + 2^B
  2. K = 2^A - 2^B

หากไม่มีอยู่จริงAและBโปรแกรมของคุณอาจทำงานในลักษณะใด ๆ (เพื่อชี้แจงAและBสามารถเท่ากับ)

กรณีทดสอบ

มักจะมีหลายวิธีในการแก้ปัญหา แต่มีเพียงไม่กี่วิธี:

K => A, B
1 => 1, 0
15 => 4, 0                      ; 16 - 1 = 15
16 => 5, 4                      ; 32 - 16 = 16; also 3, 3: 8 + 8 = 16
40 => 5, 3                      ; 2^5 + 2^3 = 40
264 => 8, 3
17179867136 => 34, 11           ; 17179869184 - 2048 = 17179867136 

กรณีการทดสอบที่ผ่านมา17179867136, ต้องทำงานในอายุต่ำกว่า 10 วินาทีในเครื่องที่ค่อนข้างทันสมัย นี่คือรหัสกอล์ฟดังนั้นโปรแกรมที่สั้นที่สุดในหน่วยไบต์ชนะ คุณอาจใช้โปรแกรมหรือฟังก์ชั่นเต็มรูปแบบ


5
Aสามารถเท่ากับB ได้หรือไม่?
Dennis

2
@ เดนนิสฉันไม่เข้าใจว่าทำไม
Conor O'Brien

... และสำหรับ16ทั้ง5,4และ3,3ถูกต้อง
ติตัส

ที่จริงตอนที่ฉันคิดเกี่ยวกับมันสามารถA, Bเป็นเชิงลบได้อย่างไร (เช่น-1, -1สำหรับ 1)
Sp3000

@ Sp3000 ไม่ดี
Conor O'Brien

คำตอบ:


3

เยลลี่ , 11 10 ไบต์

;0+N&$BL€’

การใช้เคล็ดลับการเล่นสองบิตจากคำตอบของ Python โดย @xnor

ทดสอบที่TryItOnline
กรณีทดสอบทั้งหมดเป็นที่TryItOnline

อย่างไร?

;0+N&$BL€’ - main link takes an argument, k, e.g 15
;0         - concatenate k with 0, e.g. [15, 0]
     $     - last two links as a monad
   N       - negate, e.g. -15
    &      - bitwise and, e.g. -15&15=1 since these two are called as a monad (one input)
  +        - add, vectorises, e.g. [16,1]
      B    - convert to binary, vectorises, e.g. [[1,0,0,0,0],[1]]
       L€  - length for each, e.g. [5,1]
         ’ - decrement, vectorises, e.g. [4,0]

15

Python 2, 43 ไบต์

lambda n:[len(bin((n&-n)+k))-3for k in n,0]

บอกได้เลยว่ามีn==2^a ± 2^b a>bจากนั้นปัจจัยอำนาจที่ยิ่งใหญ่ที่สุดของ 2 nคือ2^bและเราสามารถค้นหาได้โดยใช้เคล็ดลับ2^b = n&-nเล็กน้อย ที่ช่วยให้เราคำนวณ2^b + nซึ่งเท่ากับทั้งหรือเพียงแค่2^a + 2 * 2^b 2^aรายการใดรายการหนึ่งมีความยาวบิตความยาวเท่ากับa* ดังนั้นเราจึงส่งออกความยาวบิตของn&-nและ(n&-n)+nคำนวณจากความยาวของการเป็นตัวแทนไบนารีของพวกเขา Python 3 เป็นอีกหนึ่งไบต์สำหรับ parens for k in(n,0)]ค่ะ

* ยกเว้นว่า2^a + 2^bมีa==b+1มีหนึ่งอีกต่อไปบิตยาว 2^(a+1)-2^bแต่ที่ดีเพราะเราสามารถตีความว่าเป็น


วิเศษมาก - ฉันมองหาซอนิดหน่อย แต่ก็ทำไม่ได้
Jonathan Allan

ลองn=4หรือ8หรือ16โปรด
ติตัส

@Titus f(2**n)ผลตอบแทน(n+1,n)และ2**(n+1)-2**n=2**nเพื่อให้ไม่มีปัญหา
Jonathan Allan

อ่า ... รูปแบบของbin()Python ในรูปแบบใด?
ติตัส

@Titus มันเป็นสตริงที่มีชั้นนำจึง0b -3
Jonathan Allan

8

JavaScript (ES6), 73 ไบต์

(n,[s,f,z]=/^1+(.*1)?(0*)$/.exec(n.toString(2)))=>[s.length-!!f,z.length]

สำหรับกรณีการลบหมายเลขแรกคือจำนวนหลักในการแทนแบบไบนารี่และหมายเลขที่สองคือจำนวนของศูนย์ต่อท้าย สำหรับกรณีเพิ่มเติมเราลบ 1 จากหมายเลขแรก หากการแทนค่าไบนารี่เป็น 1s ทั้งหมดตามด้วย 0s บางกรณีจะถูกเพิ่มเข้ามามิฉะนั้นจะถือว่าเป็นกรณีการลบ พอร์ตขนาด 36 ไบต์ของรุ่น @ xnor ที่ใช้งานได้เพียง 30 บาทใน JavaScript:

n=>[(l=Math.log2)(n+(n&=-n))|0,l(n)]

2
@ETHproductions แน่นอน แต่ฉันตีมันลงที่ 36
Neil

ไม่ดีของฉันฉันคิดว่ารุ่น 36 ไบต์ไม่ทำงานสำหรับกรณีทดสอบ 17 พันล้าน
ETHproductions

@ETHproductions มันไม่ได้ แต่จากนั้นก็ไม่ได้ทำพอร์ตของคุณในขณะที่ฉันจำได้ (ความคิดเห็นตั้งแต่ลบแล้วถอนหายใจ) เนื่องจากมันใช้การดำเนินงานระดับบิต
Neil

ขออภัยที่นี่เป็นอีกครั้ง: n=>[n,0].map(k=>((n&-n)+k).toString(2).length-1)และทั้งสองเวอร์ชันกลับมา[34,11]ในกรณีทดสอบล่าสุด (ฉันใช้ FF 48)
ETHproductions

@ETHproductions Aha ทำงานได้อย่างแม่นยำมากขึ้นเมื่อผลลัพธ์ที่สองคือ 30 หรือน้อยกว่า
Neil

6

Perl, 52 49 32 ไบต์

โซลูชันเก่า (49 ไบต์)

รวม +1 สำหรับ -p

ให้อินพุตบน STDIN:

pow2.pl <<< 17179867136

pow2.pl

#!/usr/bin/perl -p
$_=reverse sprintf"%b",$_;/()1(?:1+|0*)/;$_="@+"

อย่างไรก็ตามการใช้อัลกอริธึมของ xnor และการเพิ่มการบิดให้ 32 ไบต์:

perl -nE 'say 13/9*log|0for$;=$_&-$_,$_+$'

เพียงแค่รหัส:

say 13/9*log|0for$;=$_&-$_,$_+$

สิ่งนี้ได้รับความทุกข์ทรมานจากความผิดพลาดในการปัดเศษที่รุนแรงเนื่องจาก13/9 = 1.444...ค่อนข้างเหนือกว่าเล็กน้อย1/log 2 = 1.44269...( logตัวมันเองยังมีข้อผิดพลาดในการปัดเศษ แต่มีขนาดเล็กกว่ามากจนเราสามารถสรุปได้ในการวิเคราะห์ 13/9) แต่เนื่องจากมีใคร2**big - 2** smallได้รับการแก้ไข2** bigก่อนที่จะบันทึกสิ่งนี้ไม่ได้เป็นวัสดุและการคำนวณสำหรับการ2**big + 2 * 2**smallตัดทอนลงดังนั้นจึงปลอดภัย .. และอีกด้านหนึ่งของช่วง2**n+2**(n-1)ไม่เพิ่มขึ้นมากพอในช่วง[0,64](ฉันไม่ถูกต้อง สนับสนุนมากกว่าช่วงจำนวนเต็มอย่างไรก็ตามเนื่องจากการใช้&) เพื่อนำไปสู่ผลลัพธ์ที่ไม่ถูกต้อง (ตัวคูณ1.5แต่จะไกลเกินไปสำหรับจำนวนมาก)


5

Brachylogขนาด 23 ไบต์

,A:B#+.:2rz:^a{+|-}?,.=

ลองออนไลน์!

นี่คือเร็วกว่าที่จำเป็นเช่นนี้ยังคงต่ำกว่า 10 วินาทีใน TIO

คำอธิบาย

นี่คือการถอดความสูตรโดยตรงโดยไม่มีการเพิ่มประสิทธิภาพ:

,A:B     The list [A, B]
#+       Both A and B are greater than or equal to 0
.        Output = [A, B]
:2rz     The list [[2, A], [2, B]]
:^a      The list [2^A, 2^B]
{+|-}?   2^A + 2^B = Input OR 2^A - 2^B = Input
,.=      Assign a value to A and B which satisfy those constraints

2
ดูเหมือนว่าความท้าทายนี้จะเกิดขึ้นกับภาษา: D
Conor O'Brien

4

Python ขนาด 69 ไบต์

def f(k):b=bin(k)[::-1];return len(b)-2-(b.count('1')==2),b.find('1')

การทดสอบอยู่บนideone

เนื่องจากอินพุตที่ไม่ถูกต้องสามารถทำอะไรได้เรารู้ว่าถ้าอินพุตมี 2 บิตอย่างแน่นอนตั้งเป็นผลรวมของ 2 พาวเวอร์ของ 2 และเป็นอย่างอื่น (ถ้าถูกต้อง) มันจะเป็นการทำงานของบิตจำนวนหนึ่ง (รวมถึง ความเป็นไปได้เพียง 1 บิต) และจะเป็นความแตกต่างระหว่างกำลังสูงสุดต่อไปของ 2 มากกว่า MSB และชุด LSB


4

จาวา 7,142 ,140, 134 BYTES

นี่คือการโพสต์ครั้งแรกของฉันใน PPCG ฉันอยากจะขอบคุณสำหรับข้อเสนอแนะเกี่ยวกับเคล็ดลับการเล่นกอล์ฟ
ขอบคุณแช่แข็งสำหรับการบันทึก 2 ไบต์

void f(long n){for(int i=-1,j;i++<31;)for(j=0;j++<34;){long a=1,x=a<<i,y=a<<j;if(x+y==n|y-x==n){System.out.println(j+" "+i);return;}}}

UNGOLF

void f(long n){
    for(int i=-1,j;i++<31;)
         for(j=0;j++<34;){
          long a=1,x=a<<i,y=a<<j;
            if(x+y==n|y-x==n){
            System.out.println(j+" "+i);
        return;
        }
            }
    }

ideone


1
สวัสดีเลข! ฉันหลงทางจากความสับสนอีกครั้งที่ฉันเห็น มันดูเหมือนจะไม่ทำงานสำหรับ40=2**3+2**5ตัวอย่างเช่น มองไปที่มันฉันไม่เห็นว่าทำไมถึงไม่ฉันอาจจะทำข้อผิดพลาดในการถอดความ ...
Jonathan Allan

1
@JanathanAllan ตอนนี้มันใช้ได้ดีจริง ๆ แล้ววงเล็บหายไปในบรรทัดนี้ถ้า ((a << i) + (a << j) == n | (a << j) - (a << i) == n ) และขอบคุณ.
Numberknot

คุณไม่สามารถใช้ตัวอักษร1แทนการประกาศตัวแปรได้ใช่ไหม
Titus

1
@TItus ถ้าฉันใช้ตัวอักษร 1 ดังนั้น testcase (17179867136) นี้คงเป็นไปไม่ได้เพราะถ้าคุณใช้ตัวอักษร 1 ดังนั้น java จะกำหนดพื้นที่หน่วยความจำ INT โดยอัตโนมัติ
Numberknot

1
คุณสามารถประกาศ j พร้อมกับ i:for(int i=-1,j;[...]
Frozn

4

Mathematica, 57 54 ไบต์

บันทึก 3 ไบต์ด้วย LegionMammal978!

Do[Abs[2^a-#]==2^b&&Print@{a,b},{a,2Log@#+1},{b,0,a}]&

พิมพ์คู่ที่เหมาะสมทั้งหมด1คู่ {a, b} จริง ๆ แล้ว 2Log@#+1เป็นขอบเขตบนสำหรับขนาดใหญ่ที่สุดaที่อาจปรากฏขึ้นเมื่อแสดงถึงอินพุต#(ขอบเขตบนที่แน่นคือ Log [2 #] / Log [2] = 1.44 ... บันทึก [#] + 1) ใช้งานอินพุตการทดสอบเกือบจะทันทีและในเวลาไม่ถึงหนึ่งในสี่วินาที (บนคอมพิวเตอร์ใหม่ แต่นอกเครื่องของฉัน) บนอินพุต 100 หลัก

1ให้aเริ่มต้นที่ค่าเริ่มต้นของ 1 แทน 0 บันทึกสองไบต์ มันทำให้เอาต์พุต {0,0} พลาดเมื่ออินพุตเป็น 2 แต่พบเอาต์พุต {2,1} ในกรณีนั้นซึ่งดีพอ


คู่ที่เหมาะสม* ทั้งหมด ? (นอกจากนี้ยังIf[Abs[2^a-#]==2^b,Print@{a,b}]สามารถแทนที่ด้วยAbs[2^a-#]==2^b&&Print@{a,b}เพื่อบันทึก 3 ไบต์)
LegionMammal978

การสังเกตที่ดีฉันเข้าใจแล้ว! "All *" เป็นเชิงอรรถ แต่ตอนนี้ชัดเจนขึ้น
Greg Martin

3

MATL , 23 22 ไบต์

BnQ:qWtG-|ym)1)tG-|hZl

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย

B      % Implicit input. Convert to binary. Gives n digits
nQ:q   % Range [1 ... n+1]
W      % 2 raised to that, element-wise: gives [1 2 4 ... 2^(n+1)] (*)
tG-|   % Duplicate. Absolute difference with input, element-wise (**)
y      % Push a copy of (*)
m      % True for elements of (**) that are members of (*)
)      % Use as logical index to select elements from (*)
1)     % Take the first element. Gives power of the first result
tG-|   % Duplicate. Absolute difference with input. Gives power of the second result
hZl    % Concatenate. Take binary logarithm. Implicit display

3

Perl 6 , 41 ไบต์

{.base(2).flip~~/1[1+|0*]/;$/.to,$/.from}

(อัลกอริทึมคัดลอกมาจากPerl 5 คำตอบ )

คำอธิบาย:

# bare block lambda with implicit parameter 「$_」
{
  # turn into binary
  # ( implicit method call on 「$_」 )
  .base(2)

  # flip the binary representation
  .flip

  ~~ # smartmatch that against:

  /
    1      # a 「1」
    [
      | 1+ # at least one 「1」
      | 0* # or any number of 「0」
    ]
  /;

  # returns a list comprised of

  # the position of the end of the match (larger of the two)
  $/.to,
  # the position of the beginning of the match
  $/.from
}

การใช้งาน:

# give it a lexical name for clarity
my &bin-sum-diff = {.base(2).flip~~/1[1+|0*]/;$/.to,$/.from}

say bin-sum-diff 15; # (4 0)
say bin-sum-diff 16; # (5 4)

say bin-sum-diff 20; # (4 2)
# 2**4==16, 2**2==4; 16+4 == 20

say bin-sum-diff 40; # (5 3)
say bin-sum-diff 264; # (8 3)
say bin-sum-diff 17179867136; # (34 11)

1

PHP, 73 ไบต์

ฉันได้คัดลอกโซลูชัน Pyhton 2 ของ Jonathan สำหรับ 54 ไบต์ (ค่าใช้จ่าย +13)
แต่อยากให้มีอะไรที่แตกต่างออกไป

บันทึกไปยังแฟ้มแล้วดำเนินการด้วยหรือphpphp-cgi

<?=strlen($n=decbin($argv[1]))-!!strpos($n,'01')._.strpos(strrev($n),49);

พิมพ์aและbคั่นด้วยเครื่องหมายขีดล่างอะไรก็ตามที่ไม่มีทางออก

โซลูชันที่โดดเด่น 96 ไบต์

<?=preg_match('#^(10*1|(1+))(0*)$#',decbin($argv[1]),$m)?strlen($m[0])-!$m[2]._.strlen($m[3]):_;

พิมพ์aและbคั่นด้วยเครื่องหมายขีดล่าง; ขีดล่าง แต่เพียงผู้เดียวโดยไม่มีวิธีแก้ปัญหา

มันยังบอกคุณการดำเนินงานสำหรับ 11 ไบต์เพิ่มเติมได้ที่: เพียงแทนที่ขีดครั้งแรกในรหัสที่มี
'-+'[!$m[2]]


ถ้าฉันลอง 67 ใน echo strlen ($ n = decbin ($ argv [1])) - !! strpos ($ n, '01 ') .'- +' [! $ n [2]]. strpos (strrev ( $ n), 49); มันให้กลับ 6 + 0 ซึ่งก็คือ 65
JörgHülsermann

@ JörgHülsermann: 67 ไม่มีวิธีแก้ปัญหา; พฤติกรรมสำหรับวิธีการแก้ปัญหาที่ไม่ได้กำหนดไว้; ดังนั้นมันจึงไม่สำคัญว่ามันจะพิมพ์อะไรสำหรับ 67.
Titus

0

PHP, 117 ไบต์

if(preg_match("#^(1+|(10*1))0*$#",$b=decbin($k=$argv[1]),$t))echo($l=strlen($b))-($t[2]?1:0).",",$l+~strrpos($b,"1");

รุ่นเพิ่มเติม 4 กรณี

$l=strlen($b=decbin($k=$argv[1]));
// Case 1: n=2(n-1)=n+n or n=n*(2-1)=2n-n 
if(preg_match('#^100*$#',$b))echo($l-2).'a+'.($l-2).':'.$l.'a-'.($l-1);
// Case 2: n-m
elseif(preg_match('#^1+0*$#',$b)){echo $l.'b-',strpos($b,"0")?$l-strpos($b,"0"):0;}
// Case 3: n+m 
elseif(preg_match('#^10*10*$#',$b))echo ($l-1).'c+',$l-strrpos($b,"1")-1;
else echo "Nothing";

การรวมเวอร์ชันสั้นของ Case 1 และ 3 และสร้างความแตกต่างให้กับ Case 3 และในทั้งสองเวอร์ชัน Case 4 ไม่ให้เอาต์พุต

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.