약간의 비트를 토글하고 사각형을 얻으십시오.


26

정수을 감안할 때 , 당신은 필요가 반전 될 수 있다는 비트의 최소 수를 찾을 수있다 로를 설정하는 사각형 번호 . 가장 중요한 비트 이하 로만 비트를 반전시킬 수 있습니다 .NN>3N

  • 2 2 0N=4 이미 제곱 수 ( )이므로 예상 출력은 입니다.220
  • 11000 1100 1 25 = 5 2 1N=24 는 1 비트 ( ( )) 를 반전하여 제곱 숫자로 바뀔 수 있으므로 예상 출력은 입니다.110001100125=521
  • 23 20 18 30 10110 10 0 0 0 16 = 4 2 2N=22 는 단일 비트를 뒤집어서 제곱 숫자로 바꿀 수 없지만 (가능한 결과는 , , 및 ) 2 비트를 으면됩니다 : ( )이므로 예상 출력은 입니다.23201830101101000016=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]

거의 절반의 답변이 100048606TIO에서 실행되지 않습니다 . 문제입니까?
Magic Octopus Urn

@MagicOctopusUrn 감사합니다. 지원 이 선택 사항 임을 더욱 명확하게하기 위해 규칙을 업데이트했습니다 . N10000
Arnauld

1
이것은 (입력 크기 제한없이) 아주 빠른 코드 질문
qwr

@qwr 그렇습니다. 또는 하드 코어로 가고 싶다면 : 주어진 , 와 같은 가장 작은 찾으십시오 . N f ( N ) = kkNf(N)=k
Arnauld

답변:


14

루비, 74 바이트

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

온라인으로 사용해보십시오!

이것은 단순히 시퀀스 생성 (훨씬 충분하다)와 배타적 논리합을 연산하여 다음과는 이진수 1의 두 수를 얻어 비트 수가 보다 작거나 같으면 , 그렇지 않으면그런 다음 플립 된 최소 비트 수를 사용합니다. 최상위 비트 플립이 보다 클 때 플립 된 비트 수 대신 을 반환 하면 이 항상 비트 수보다 크므 로 이러한 경우가 최소값으로 선택되지 않습니다 . 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

@ 피콜로 내가 그것을 그리워 믿을 수 없어, 감사합니다!
Doorknob

6

젤리 , 12 바이트

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

온라인으로 사용해보십시오!

테스트 스위트를 확인하십시오!

모나 딕 링크. 골프를 타야합니다. 그러나 나는 ³s를 제거하는 방법을 생각하기에는 너무 바보 입니다. 그것은 일반적으로 가변 체인 \ o /와 함께 필터링 / 매핑 / 루핑을 성공적으로 사용하는 첫 번째 대답입니다.

설명

², BẈEðƇ² ^ B§Ṃ – 전체 프로그램 / Monadic 링크. 인수 N을 부릅니다.
     ðƇ – 다음과 같은 2 차원 체인으로 필터 유지 [1 ... N] :
², BẈE – 현재 항목의 제곱은 비트 길이가 N과 같습니다.
² – 정사각형.
 – N과 페어링합니다.
  B – 둘 다 이진으로 변환합니다.
   Ẉ – 길이를 검색합니다.
    E – 그리고 그들이 일치하는지 확인하십시오.
       ² ^ – 필터링 후 결과를 제곱하고 N으로 XOR합니다.
         B – 각각의 이진 표현.
          § – 각각의 합. 이진수로 1의 수를 셉니다.
           Ṃ – 최소.

5

껍질 , 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

펄 6 , 65 바이트

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

온라인으로 사용해보십시오!

숫자의 제곱근의 문자열 표현에서 마침표를 찾아서 완벽한 제곱을 테스트하기에는 약간 더러운 느낌이 들지만 바이트를 삭감해야 할 것은 아무것도 없습니다.


4

05AB1E , 20 15 바이트

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

그의 Jelly 응답 포트를 사용하는 @ Mr.Xcoder 덕분에 -5 바이트 .

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 (60 초 후에 시간 초과되어 최대 3 개의 테스트 사례가 제거되지만 다른 테스트 사례와 함께 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ß입니다. 그러나 불행히도 테스트 스위트를 중단합니다
Mr. Xcoder

1
@ Mr.Xcoder 감사합니다! 그리고 골프가 끝난 후에도 테스트 스위트는 거의 항상 중단됩니다.
Kevin Cruijssen

05AB1E ¯ \ _ (ツ) _ / ¯에서 테스트 스위트를 작성하는 데 능숙하지 않다고 생각합니다. 문제를 해결 한 것이 좋습니다 :)
Mr. Xcoder


3

가이아 , 18 바이트

내 젤리 답변 근처 포트 .

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

온라인으로 사용해보십시오!

고장

s¦⟪, b¦l¦y⟫⁇ ⟪^ bΣ⟫¦⌋ – 전체 프로그램. 입력 N을 호출합시다.
– [1 ... N] 범위에서 각 정수를 제곱합니다.
  ⟪⟫⁇ – 통과 할 때 특정 조건을 충족하는 것을 선택합니다
                     이차원 블록. Dyadic 블록을 사용하면 1 바이트가 절약됩니다.
                     입력 N은 다른 인수로 내재적으로 사용됩니다.
   , – 현재 요소와 목록에서 N을 쌍으로 만듭니다.
    b¦ – 이진수로 변환합니다.
      l – 그들의 길이를 가져옵니다.
        y – 그런 다음 동일한 지 확인하십시오.
           ya ⟫¦ – 이진 블록을 통해 유효한 모든 정수를 실행합니다.
            ^ – 각각 N과 XOR.
             bΣ – 이진수와 합계로 변환 (1을 이진수로 계산)
                 ⌋ – 최소.

2

Brachylog , 56 41 바이트

길이 기록을 깰 수는 없지만 어쨌든 게시 할 것이라고 생각했습니다.

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

온라인으로 사용해보십시오!


단지 압축이 중요하다는 것을 깨달았습니다. 식당에서 돌아온 후 단축하겠습니다
Kroppeb

1
@Arnauld 그래, 주요 문제는 range (0, n + 1)의 각 i에 대해 범위를 다시 계산하고, 제곱하고 이진으로 계산한다는 것입니다. 이것을 외부에두면 몇 바이트가 더 필요하지만 지금은 더 빠릅니다.
Kroppeb

2

x86-64 어셈블리, 37 바이트

바이트 코드 :

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

멋지게, 이것은 1 초 안에 가장 높은 예조차도 계산합니다.

알고리즘의 핵심은 평소와 같이 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
ceilingcat

내가 말할 수있는 한 바이트 ( 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)생각합니다.


ungolfed 및 주석이 달린 코드 :

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

편집 :

  • ceilingcat 덕분에 2 바이트 절약
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.