แยกพลิกและรวบรวมจำนวนเต็มอีกครั้ง


16

พื้นหลัง

เป็นที่รู้จักกันดีในวิชาคณิตศาสตร์ที่สามารถใส่จำนวนเต็มลงในการติดต่อแบบหนึ่งต่อหนึ่งกับคู่ของจำนวนเต็ม มีหลายวิธีที่เป็นไปได้ในการทำเช่นนี้และในการท้าทายนี้คุณจะใช้หนึ่งในนั้นและการดำเนินการแบบผกผัน

งาน

n > 0ข้อมูลของคุณเป็นจำนวนเต็มบวก เป็นที่ทราบกันว่ามีอยู่จำนวนเต็มไม่ซ้ำกันที่ไม่ใช่เชิงลบดังกล่าวว่าa, b ≥ 0 การส่งออกของคุณเป็นรุ่น "พลิก" ของที่จำนวนเต็มบวกn == 2a * (2*b + 1)n2b * (2*a + 1)

คุณสามารถสันนิษฐานได้ว่าอินพุตและเอาต์พุตเหมาะสมกับประเภทข้อมูลจำนวนเต็มแบบไม่ได้ลงนามมาตรฐานของภาษาของคุณ

กฎและการให้คะแนน

คุณสามารถเขียนโปรแกรมเต็มหรือฟังก์ชั่น จำนวนไบต์ต่ำสุดที่ชนะและช่องโหว่มาตรฐานไม่ได้รับอนุญาต

กรณีทดสอบ

สิ่งเหล่านี้ถูกกำหนดในรูปแบบin <-> outเนื่องจากฟังก์ชั่นที่จะใช้งานนั้นเป็นค่าผกผันของตัวเอง: หากคุณป้อนข้อมูลกลับคืนคุณควรรับอินพุตต้นฉบับ

1 <-> 1
2 <-> 3
4 <-> 5
6 <-> 6
7 <-> 8
9 <-> 16
10 <-> 12
11 <-> 32
13 <-> 64
14 <-> 24
15 <-> 128
17 <-> 256
18 <-> 48
19 <-> 512
20 <-> 20
28 <-> 40
30 <-> 384
56 <-> 56
88 <-> 224
89 <-> 17592186044416

ลีดเดอร์บอร์ด

นี่คือตัวอย่างข้อมูลเพื่อสร้างทั้งกระดานผู้นำปกติและภาพรวมของผู้ชนะตามภาษา เพื่อให้แน่ใจว่าคำตอบของคุณปรากฏขึ้นโปรดเริ่มคำตอบด้วยหัวข้อโดยใช้เทมเพลต Markdown ต่อไปนี้:

## Language Name, N bytes

ที่Nมีขนาดของส่งของคุณ หากคุณปรับปรุงคะแนนของคุณคุณสามารถเก็บคะแนนเก่าไว้ในบรรทัดแรกโดยการตีพวกเขาผ่าน ตัวอย่างเช่น

## Ruby, <s>104</s> <s>101</s> 96 bytes

หากคุณต้องการรวมหลายตัวเลขไว้ในส่วนหัวของคุณ (เช่นเนื่องจากคะแนนของคุณคือผลรวมของสองไฟล์หรือคุณต้องการแสดงรายการการลงโทษการตั้งค่าสถานะของล่ามแยกต่างหาก) ตรวจสอบให้แน่ใจว่าคะแนนจริงเป็นตัวเลขสุดท้ายในส่วนหัว:

## Perl, 43 + 2 (-p flag) = 45 bytes

นอกจากนี้คุณยังสามารถตั้งชื่อภาษาให้เป็นลิงค์ซึ่งจะปรากฏในตัวอย่างกระดานแต้มนำ:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes



@feersum โอ้ฉันไม่รู้ เป็นเรื่องบังเอิญ
Zgarb

2
บังคับxkcd.com/153
corsiKa

คำตอบ:


11

เยลลี่ , 17 16 15 ไบต์

BUi1µ2*³:2*×Ḥ’$

ลองออนไลน์!

มันทำงานอย่างไร

BUi1µ2*³:2*×Ḥ’$    Main link. Input: n

B                  Convert n to base 2.
 U                 Reverse the array of binary digits.
  i1               Get the first index (1-based) of 1.
                   This yields a + 1.
    µ              Begin a new, monadic chain. Argument: a + 1
     2*            Compute 2 ** (a+1).
       ³:          Divide n (input) by 2 ** (a+1).
                   : performs integer division, so this yields b.
         2*        Compute 2 ** b.
              $    Combine the two preceding atoms.
            Ḥ      Double; yield 2a + 2.
             ’     Decrement to yield 2a + 1.
           ×       Fork; multiply the results to the left and to the right.

เดี๋ยวก่อนคุณกำลังใช้โอเปอเรเตอร์ในเยลลี่เพื่อให้เหมาะกับปัญหาหรือไม่ ในกรณีนี้ LOL
Alexander Torstling

ฉันไม่. ความมุ่งมั่นต่อเยลลี่เพียงอย่างเดียวหลังจากมีการโพสต์ความท้าทายนี้คือการอัปเดตเอกสารประกอบและผู้ดำเนินการทั้งหมดที่ใช้ในคำตอบนี้ได้รับการดำเนินการอย่างน้อยหนึ่งเดือน อย่าลังเลที่จะตรวจสอบ
Dennis

ไม่ต้องกังวลฉันไม่คุ้นเคยกับกฎเกณฑ์หรืออะไรฉันแค่คิดว่ามันเจ๋งที่การเล่นกอล์ฟมาถึงผู้ที่คิดค้นภาษาของตัวเอง!
Alexander Torstling


10

Pyth, 16 15 ไบต์

*hyJ/PQ2^2.>QhJ

1 ไบต์ต้องขอบคุณเดนนิส

ชุดทดสอบ

คำอธิบาย:

*hyJ/PQ2^2.>QhJ
                    Implicit: Q = eval(input())
     PQ             Take the prime factorization of Q.
    /  2            Count how many 2s appear. This is a.
   J                Save it to J.
  y                 Double.
 h                  +1.
          .>QhJ     Shift Q right by J + 1, giving b.
        ^2          Compute 2 ** b.
*                   Multiply the above together, and print implicitly.

7

MATL , 22 ไบต์

Yft2=XK~)pq2/2w^Ks2*Q*

ลองออนไลน์!

คำอธิบาย

Yf      % factor
t       % duplicate
2=      % compare to 2 (yields a logical array)
XK      % save a copy of that to variable K
~)      % keep only values != 2 in the factors array
p       % multiply that factors
q2/     % product - 1 / 2
2w^     % 2^x

K       % load variable K (the logical array)
s       % sum (yields the number of 2s)
2*Q     % count * 2 + 1

*       % multiply both values

ดีมาก! คุณสามารถใช้Qสำหรับ1+(ซึ่งได้รับการแนะนำเมื่อเร็ว ๆ นี้) และสำหรับq 1-นอกจากนี้ยังช่วยประหยัดพื้นที่ (ซึ่งคุณสามารถบันทึกได้ด้วยH) ดูที่นี่
Luis Mendo

@LuisMendo ขอบคุณ ไม่ทราบคุณลักษณะนั้น
Rainer P.

5
ทำได้ดีมากถ้าหลุยส์ใช้ MATLAB!
Stewie Griffin

6

Python 2, 39 ไบต์

lambda n:2*len(bin(n&-n))-5<<n/2/(n&-n)

n & -nให้พลังงานที่ใหญ่ที่สุดของ 2 nที่แบ่ง มันทำงานได้เพราะในสองส่วนเสริมเลขคณิต, -n == ~n + 1. หากnมีศูนย์kต่อท้ายการเติมเต็มจะทำให้มันมีkต่อท้าย จากนั้นการเพิ่ม 1 จะเปลี่ยนค่าทั้งหมดต่อท้ายเป็นศูนย์และเปลี่ยนบิต2 ^ kจาก 0 เป็น 1 ดังนั้น-nลงท้ายด้วย 1 ตามด้วยk 0 ของ (เช่นn) ในขณะที่มีบิตตรงกันข้ามจากที่nสูงขึ้นทั้งหมด


คุณสามารถอธิบายวิธีการn&-nทำงานในไม่ช้า ฉันเห็นสิ่งที่เคล็ดลับนี้ทำ แต่ไม่ใช่ว่า :(
Erwan

n&-nผลตอบแทนที่ได้อำนาจสูงสุดของ 2 ที่ ndivdes
Neil

@Erwan n & -nผมอธิบายเกี่ยวกับ
feersum

ฉันได้รับโปรแกรมที่เกี่ยวข้องกับ Anarchy golf n=1;exec"c=n&-n;print n,':',2*len(bin(c))-5<<n/2/c;n+=1;"*100แต่มันมีสองตัวอักษรที่อยู่เบื้องหลังทางออกที่ดีที่สุด
xnor

@xnor คำแนะนำ: การแก้ปัญหา 59 ไบต์ (ดีเหมืองอย่างน้อย) nไม่ทำงานสำหรับทุกค่าของ
feersum

6

MATL , 25 26ไบต์

:qt2w^w!2*Q*G=2#f2*q2bq^*

สิ่งนี้ใช้รีลีสปัจจุบัน (10.2.1)ของภาษา / คอมไพเลอร์

ลองออนไลน์!

คำอธิบาย

ค่อนข้างตรงไปตรงมาตามแรงเดรัจฉาน พยายามรวมกันทั้งหมดของaและbเลือกชุดที่เหมาะสมและทำการคำนวณที่จำเป็น

:q          % implicit input "n". Generate row vector [0,1,...,n-1], say "x"
t2w^        % duplicate and compute 2^x element-wise
w!2*Q       % swap, transpose to column vector, compute 2*x+1
*           % compute all combinations of products. Gives 2D array
G=2#f       % find indices where that array equals n
2*q2bq^*    % apply operation to flipped values

1
ฮะ! :-P พ่ายแพ้ในภาษาของคุณเอง ... ครั้งแรก?
Stewie Griffin

@StewieGriffin ใช่แล้ว! เหตุการณ์สำคัญ :-)
Luis Mendo

5

Julia, 41 ไบต์

n->2^(n>>(a=get(factor(n),2,0)+1))*(2a-1)

นี่เป็นฟังก์ชั่นนิรนามที่รับจำนวนเต็มและคืนค่าจำนวนเต็ม หากต้องการเรียกใช้กำหนดค่าให้กับตัวแปร

เรากำหนดaเป็น 1 + ยกกำลัง 2 nในตัวประกอบที่สำคัญของ เนื่องจากfactorผลตอบแทนDictที่เราสามารถใช้getกับค่าเริ่มต้นของ 0 ในกรณีที่ตัวประกอบที่สำคัญไม่ได้มี 2 เรากะบิตที่เหมาะสมnโดยaและใช้เวลา 2 ถึงอำนาจนี้ เราคูณมันด้วย2a-1เพื่อให้ได้ผลลัพธ์


4

Perl 5, 40 ไบต์

38 ไบต์บวก 2 สำหรับ -p

$i++,$_/=2until$_%2;$_=2*$i+1<<$_/2-.5

-p อ่าน STDIN ลงในตัวแปร $_ลงในตัวแปร

$i++,$_/=2until$_%2การเพิ่มขึ้น$i(ซึ่งเริ่มต้นที่ 0) และลดลงครึ่งหนึ่ง$_จนกระทั่ง$_ไม่ใช่ศูนย์ mod 2 หลังจากนั้น$_เป็นปัจจัยคี่ของหมายเลขเดิมและ$iเป็นเลขชี้กำลังของ 2

$_=2*$i+1<<$_/2-.5- ด้านขวาของ=สูตรเป็นเพียงจำนวนที่ต้องการ: {1 มากกว่าสองเท่าของเลขชี้กำลัง 2} คูณ {2 ต่อกำลังของ {ครึ่งตัวคูณเป็นลบคูณครึ่ง}} แต่ "คูณ {2 ถึงพลังของ ... }" ก็กอล์ฟเหมือน "บิตเลื่อนไปทางซ้ายโดย ... " และทางขวามือนั้นถูกกำหนดให้$_และที่ด้านขวามือได้รับมอบหมายให้

และภาพพิมพ์-p$_



2

JavaScript ES6, 36 33 ไบต์

n=>63-2*Math.clz32(b=n&-n)<<n/b/2

ความเข้าใจของฉันคือ Math.clz32จะสั้นกว่าที่เล่นซอกับtoString(2).lengthเป็นไปได้สั้นกว่าที่เล่นซอรอบกับ

แก้ไข: บันทึกแล้ว 3 ไบต์ด้วย @ user81655


ดี คุณสามารถบันทึกสองสามไบต์โดยการตั้งค่าn&-nเป็นตัวแปร:n=>63-2*Math.clz32(x=n&-n)<<n/x/2
user81655

@ user81655 ขอบคุณ; ฉันแค่หวังว่าฉันจะสามารถใช้n&=-nแต่ฉันต้องการnอีกครั้ง ...
Neil

1

PARI / GP , 38 ไบต์

f(n)=k=valuation(n,2);(2*k+1)<<(n>>k\2)

โปรดทราบว่า>>และ\มีลำดับความสำคัญเท่ากันและคำนวณจากซ้ายไปขวาดังนั้นส่วนสุดท้ายสามารถn>>k\2แทน(n>>k)\2ได้ เวอร์ชั่นที่ไม่ดีจะทำให้kศัพท์มีmy:

f(n)=
{
  my(k=valuation(n,2));
  (2*k+1) << ((n>>k)\2);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.