สลับบิตและรับสี่เหลี่ยมจัตุรัส


26

ได้รับจำนวนเต็มคุณต้องไปหาจำนวนขั้นต่ำของบิตที่จะต้องมีการคว่ำในจะทำให้มันกลายเป็นจำนวนตาราง คุณได้รับอนุญาตให้สลับบิตด้านล่างที่สำคัญที่สุดเท่านั้นNN>3N

ตัวอย่าง

  • N=4แล้วเป็นจำนวนตาราง ( ) เพื่อการส่งออกที่คาดว่าจะเป็น0 0220
  • N=24สามารถเปิดเป็นจำนวนตารางโดย inverting 1 บิต: ( ) เพื่อการส่งออกที่คาดว่าจะเป็น1 25 = 5 2 1110001100125=521
  • N=22ไม่สามารถเปลี่ยนเป็นจำนวนตารางได้โดยแปลงกลับเป็นบิตเดียว (ผลลัพธ์ที่เป็นไปได้คือ , ,และ ) แต่สามารถทำได้โดยสลับกลับ 2 บิต: ( ) เพื่อการส่งออกที่คาดว่าจะเป็น220 18 30 10110 10 0 0 0 16 = 4 2 223201830101101000016=422

กฎระเบียบ

  • มันเป็นเรื่องที่ดีถ้ารหัสของคุณช้าเกินไปหรือเกิดข้อผิดพลาดสำหรับกรณีทดสอบที่ใหญ่กว่า แต่อย่างน้อยควรรองรับในเวลาน้อยกว่า 1 นาที3<N<10000
  • นี่คือ !

กรณีทดสอบ

    Input | Output
----------+--------
        4 | 0
       22 | 2
       24 | 1
       30 | 3
       94 | 4
      831 | 5
      832 | 1
     1055 | 4
     6495 | 6
     9999 | 4
    40063 | 6
   247614 | 7        (smallest N for which the answer is 7)
  1049310 | 7        (clear them all!)
  7361278 | 8        (smallest N for which the answer is 8)
100048606 | 8        (a bigger "8")

หรือในรูปแบบที่เป็นมิตรคัดลอก / วาง:

[4,22,24,30,94,831,832,1055,6495,9999,40063,247614,1049310,7361278,100048606]

เกือบครึ่งหนึ่งของคำตอบไม่ได้ดำเนินการ100048606กับ TIO นั่นเป็นปัญหาหรือไม่
Magic Octopus Urn

@MagicOctopusUrn ขอบคุณฉันได้อัปเดตกฎเพื่อให้ชัดเจนยิ่งขึ้นว่ารองรับเป็นตัวเลือก N10000
Arnauld

1
นี้จะเป็นที่ดีเร็วที่สุดรหัสคำถามเช่นกัน (โดยไม่มีข้อ จำกัด ขนาดการป้อนข้อมูล)
qwr

@qwr ใช่อาจเป็นไปได้ หรือถ้าคุณต้องการที่จะไปไม่ยอมใครง่ายๆ: รับหาที่เล็กที่สุดเช่นว่าk N f ( N ) = kkNf(N)=k
Arnauld

คำตอบ:


14

Ruby, 74 ไบต์

->n{(1..n).map{|x|a=(n^x*x).to_s 2;a.size>Math.log2(n)?n:a.count(?1)}.min}

ลองออนไลน์!

สิ่งนี้จะสร้างลำดับ (ซึ่งไกลเกินพอ), XORs ด้วยและจากนั้นใช้ 1s ในเลขฐานสอง แทนถ้าจำนวนบิตน้อยกว่าหรือเท่ากับหรืออื่น จากนั้นใช้จำนวนบิตต่ำสุดที่พลิก การคืนค่าแทนจำนวนบิตที่พลิกเมื่อบิตสูงสุดที่พลิกมากกว่าป้องกันกรณีเหล่านี้ไม่ให้ถูกเลือกเป็นค่าต่ำสุดเนื่องจากจะมากกว่าจำนวนบิตที่มีเสมอ n log 2 nnn log 2 nn[12,22,,n2]nlog2nnnlog2nn

ขอบคุณPiccoloสำหรับการบันทึกไบต์


คุณสามารถบันทึกไบต์โดยใช้(n^x*x).to_s 2;...แทน(n^x*x).to_s(2);...
Piccolo

@Piccolo ไม่อยากเชื่อเลยว่าฉันพลาดไปขอบคุณ!
Doorknob

6

เยลลี่ 12 ไบต์

²,BẈEðƇ²^B§Ṃ

ลองออนไลน์!

ลองชุดทดสอบ!

ลิงก์ Monadic ควรเล่นกอล์ฟได้ แต่ฉันโง่เกินไปที่จะคิดวิธีที่จะกำจัด³มันออกไป มันเป็นคำตอบแรกของฉันที่ฉันใช้การกรอง / การแมป / การวนลูปโดยทั่วไปพร้อมกับโซ่ dyadic \ o /

คำอธิบาย

², BẈEðƇ² ^ B§Ṃ - โปรแกรมเต็มรูปแบบ / ลิงก์ Monadic เรียกอาร์กิวเมนต์ N
     ðƇ - กรอง - เก็บ [1 ... N] ด้วยโซ่ dyadic ต่อไปนี้:
², BẈE - สี่เหลี่ยมจัตุรัสของรายการปัจจุบันมีความยาวบิตเท่ากับ N
² - สแควร์
 , - จับคู่กับ N
  B - แปลงทั้งสองเป็นไบนารี
   Ẉ - ดึงความยาวของพวกเขา
    E - และตรวจสอบว่าพวกเขาถือเอา
       ² ^ - หลังจากกรองแล้วให้จัดเรียงผลลัพธ์และ XOR ด้วย N
         B - ตัวแทนไบนารีของแต่ละคน
          § - ผลรวมของแต่ละ นับจำนวน 1s ในไบนารี
           Ṃ - ขั้นต่ำ

5

Husk , 20 ไบต์

▼mΣfo¬→S↑(Mo¤ż≠↔ḋİ□ḋ

ลองออนไลน์!

คำอธิบาย

▼mΣf(¬→)S↑(M(¤ż≠↔ḋ)İ□ḋ) -- example input n=4
        S↑(           ) -- take n from n applied to (..)
                     ḋ  -- | convert to binary: [1,0,0]
                   İ□   -- | squares: [1,4,9,16,...]
           M(     )     -- | map with argument ([1,0,0]; example with 1)
                 ḋ      -- | | convert to binary: [1]
             ¤  ↔       -- | | reverse both arguments of: [1] [0,0,1]
              ż≠        -- | | | zip with inequality (absolute difference) keeping longer elements: [1,0,1]
                        -- | : [[1,0,1],[0,0,0],[1,0,1,1],[0,0,1,0,1],[1,0,1,1,1],....
                        -- : [[1,0,1],[0,0,0],[1,0,1,1],[0,0,1,0,1]]
    f(  )               -- filter elements where
       →                -- | last element
      ¬                 -- | is zero
                        -- : [[0,0,0]]
 mΣ                     -- sum each: [0]
▼                       -- minimum: 0

▼mΣfo¬←ṠMz≠ȯfo£İ□ḋπŀ2Lḋบันทึก 2 ไบต์ RIP คุณคะแนนสแควร์ที่สมบูรณ์แบบ
Mr. Xcoder

@ Mr.Xcoder: ความอัปยศเกี่ยวกับคะแนน .. แต่ฉันได้กำจัดบางอย่างตอนนี้กำหนดเป้าหมาย 16; P
เริ่ม

5

Perl 6 , 65 ไบต์

{min map {+$^a.base(2).comb(~1) if sqrt($a+^$_)!~~/\./},^2**.msb}

ลองออนไลน์!

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


4

05AB1E , 20 15 ไบต์

Lnʒ‚b€gË}^b€SOß

-5 ไบต์ขอบคุณที่@ Mr.Xcoderใช้พอร์ตของคำตอบของเขาวุ้น

ลองใช้ออนไลน์หรือตรวจสอบกรณีทดสอบทั้งหมด (สามกรณีทดสอบที่ใหญ่ที่สุดจะถูกลบออกเพราะหมดเวลาหลังจาก 60 วินาทียังคงใช้เวลาประมาณ 35-45 วินาทีกับกรณีทดสอบอื่น ๆ )

คำอธิบาย:

L            # Create a list in the range [1, input]
             #  i.e. 22 → [0,1,2,...,20,21,22]
 n           # Take the square of each
             #  i.e. [0,1,2,...,20,21,22] → [0,1,4,...,400,441,484]
  ʒ     }    # Filter this list by:
   ,         #  Pair the current value with the input
             #   i.e. 0 and 22 → [0,22]
             #   i.e. 25 and 22 → [25,22]
    b        #  Convert both to binary strings
             #   i.e. [0,22] → ['0','10110']
             #   i.e. [25,22] →  ['10000','11001']
     g      #  Take the length of both
             #   i.e. ['0','10110'] → [1,5]
             #   ['10000','11001'] → [5,5]
       Ë     #  Check if both are equal
             #   i.e. [1,5] → 0 (falsey)
             #   i.e. [5,5] → 1 (truthy)
^            # After we've filtered, Bitwise-XOR each with the input
             #  i.e. [16,25] and 22 → [6,15]
 b           # Convert each to a binary string again
             #  i.e. [6,15] → ['110','1111']
  S         # Change the binary strings to a list of digits
             #  i.e. ['110','1111'] → [['1','1','0'],['1','1','1','1']]
    O        # Take the sum of each
             #  i.e. [['1','1','0'],['1','1','1','1']] → [2,4]
ß            # And then take the lowest value in the list
             #  i.e. [2,4] → 2

1
เอาล่ะแล้วที่ถูกต้อง 15 Lnʒ‚b€gË}^b€SOßbyter: มันแบ่งชุดทดสอบของคุณโชคไม่ดีแม้ว่า
นาย Xcoder

1
@ Mr.Xcoder ขอบคุณ! และชุดทดสอบของฉันมักจะหยุดพักหลังจากที่ฉันตีกอล์ฟอะไรบางอย่าง .. XD แต่ตอนนี้มันได้รับการแก้ไขแล้วเช่นกัน
Kevin Cruijssen

ฉันเดาว่าฉันไม่เก่งในการเขียนชุดทดสอบใน 05AB1E ¯ \ _ (ツ) _ / ¯มันเป็นเรื่องดีที่คุณได้ซ่อมมัน :)
นาย Xcoder


3

Gaia ขนาด 18 ไบต์

ใกล้ท่าเรือคำตอบวุ้นของฉัน

s¦⟪,b¦l¦y⟫⁇⟪^bΣ⟫¦⌋

ลองออนไลน์!

ทำให้พังถล่ม

s¦⟪, b¦l¦y⟫ ⁇⟪ ^ bΣ⟫¦⌋ - โปรแกรมเต็มรูปแบบ ลองเรียกอินพุต N
s¦ - สแควร์แต่ละจำนวนเต็มในช่วง [1 ... N]
  ⟪⟫ ⁇ - เลือกสิ่งที่ตรงตามเงื่อนไขเมื่อวิ่งผ่าน
                     บล็อก dyadic การใช้บล็อก dyadic จะบันทึกหนึ่งไบต์เนื่องจาก
                     อินพุต, N, ถูกใช้โดยนัยเป็นอาร์กิวเมนต์อื่น
   , - จับคู่อิลิเมนต์ปัจจุบันและ N ในรายการ
    b¦ - แปลงเป็นไบนารี่
      l¦ - รับความยาว
        y - จากนั้นตรวจสอบว่ามันเท่ากันหรือไม่
           ⟪ ⟫¦ - เรียกใช้จำนวนเต็มที่ถูกต้องทั้งหมดผ่านบล็อก dyadic
            ^ - XOR แต่ละอันด้วย N
             bΣ - แปลงเป็นไบนารี่และผลรวม (นับ 1 ในหน่วยไบนารี่)
                 ⌋ - ขั้นต่ำ

2

Brachylog , 56 41 ไบต์

มันจะไม่ทำลายสถิติความยาว แต่คิดว่าฉันจะโพสต์ต่อไป

⟨⟨{⟦^₂ᵐḃᵐ}{h∋Q.l~t?∧}ᶠ{ḃl}⟩zḃᶠ⟩{z{∋≠}ᶜ}ᵐ⌋

ลองออนไลน์!


การตระหนักถึงการซิปก็เป็นสิ่งหนึ่ง ฉันจะสั้นลงหลังจากที่ฉันกลับมาจากร้านอาหาร
Kroppeb

1
@ Arnauld ใช่ปัญหาหลักคือว่าสำหรับฉันแต่ละคนในช่วง (0, n + 1) ฉันคำนวณช่วงใหม่, ยกกำลังสองมันและไบนารี การนำสิ่งนี้ไปใช้ภายนอกได้รับอีกสองสามไบต์ แต่ตอนนี้มันเร็วขึ้นแล้ว
Kroppeb

2

ชุดประกอบ x86-64, 37 ไบต์

bytecode:

53 89 fb 89 f9 0f bd f7 89 c8 f7 e0 70 12 0f bd
d0 39 f2 75 0b 31 f8 f3 0f b8 c0 39 d8 0f 42 d8
e2 e6 93 5b c3

อย่างนี้คำนวณแม้ตัวอย่างสูงสุดในเวลาน้อยกว่าหนึ่งวินาที

หัวใจของอัลกอริทึมคือ xor / popcount ตามปกติ

    push %rbx
    /* we use ebx as our global accumulator, to see what the lowest bit
     * difference is */
    /* it needs to be initialized to something big enough, fortunately the
     * answer will always be less than the initial argument */
    mov %edi,%ebx
    mov %edi,%ecx
    bsr %edi,%esi
.L1:
    mov %ecx,%eax
    mul %eax
    jo cont     /* this square doesn't even fit into eax */
    bsr %eax,%edx
    cmp %esi,%edx
    jnz cont    /* can't invert bits higher than esi */
    xor %edi,%eax
    popcnt %eax,%eax
    cmp %ebx,%eax   /* if eax < ebx */
    cmovb %eax,%ebx
cont:
    loop .L1
    xchg %ebx,%eax
    pop %rbx
    retq

แนะนำให้เปลี่ยนอย่างน้อยหนึ่งตัวของคุณmovด้วยxchg
catcat

เท่าที่ฉันสามารถบอกได้ว่ามีเพียงหนึ่งเดียวเท่านั้นที่จะบันทึกไบต์ ( mov %ecx,%eax) และฉันไม่สามารถปล่อยให้% ecx ตายที่นั่นได้
ObsequiousNewt


1

ถ่าน , 31 ไบต์

NθI⌊EΦEθ↨×ιι²⁼LιL↨θ²ΣE↨責⁼λ§ιμ

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด คำอธิบาย:

Nθ                              Input N
       θ                        N
      E                         Map over implicit range
          ιι                    Current value (twice)
         ×                      Multiply
        ↨   ²                   Convert to base 2
     Φ                          Filter over result
               ι                Current value
                  θ             N
                 ↨ ²            Convert to base 2
              L L               Length
             ⁼                  Equals
    E                           Map over result
                       θ        N
                      ↨ ²       Convert to base 2
                     E          Map over digits
                           λ    Current base 2 digit of N
                             ι  Current base 2 value
                              μ Inner index
                            §   Get digit of value
                          ⁼     Equals
                         ¬      Not (i.e. XOR)
                    Σ           Take the sum
   ⌊                            Take the minimum
  I                             Cast to string
                                Implicitly print




1

C (gcc) ,  93  91 ไบต์

g(n){n=n?n%2+g(n/2):0;}m;i;d;f(n){m=99;for(i=0;++i*i<2*n;m=g(d=i*i^n)<m&d<n/2?g(d):m);n=m;}

ลองออนไลน์!


แก้ไข: ฉันคิดว่าโซลูชันดั้งเดิมของฉัน ( ลองออนไลน์! ) ไม่ถูกต้องเนื่องจากตัวแปรตัวใดตัวหนึ่งmทั่วโลกบันทึกไม่กี่ไบต์โดยไม่ระบุประเภทเริ่มต้นนอกf(n)แล้วจึงต้องเริ่มต้นใหม่ระหว่างการโทร


รหัสที่ไม่ได้บรรจุและแสดงความคิดเห็น:

g(n){n=n?n%2+g(n/2):0;} // returns the number of bits equal to 1 in n
m; //miminum hamming distance between n and a square
i; //counter to browse squares
d; //bitwise difference between n and a square
f(n){m=99; //initialize m to 99 > size of int (in bits)
    for(
        i=0;
        ++i*i<2*n; //get the next square number, stop if it's greater than 2*n
        g(d=i*i^n)<m&&d<n/2&&(m=g(d)) //calculate d and hamming distance
//      ^~~~~~~~~~~^ if the hamming distance is less than the minimum
//                    ^~~~^ and the most significant bit of n did not change (the most significant bit contains at least half the value)
//                           ^~~~~~~^ then update m
       );
    n=m;} // output m

การแก้ไข:

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