Nhân đôi, XOR và làm lại


20

Chúng tôi xác định hàm gg (n) = n XOR (n * 2) cho mọi số nguyên n> 0 .

Cho x> 0 , tìm số nguyên nhỏ nhất y> 0 sao cho g k (y) = x với một số k> 0 .

Thí dụ

x = 549

549 = 483 XOR (483 * 2)     (as binary: 1000100101 = 111100011 XOR 1111000110)
483 = 161 XOR (161 * 2)     (as binary:  111100011 =  10100001 XOR  101000010)

Có nghĩa là g 2 (161) = 549 . Chúng ta không thể đi xa hơn, vì không có n sao cho g (n) = 161 . Vì vậy, sản lượng dự kiến ​​cho x = 549y = 161 .

Quy tắc

  • Bạn không cần phải hỗ trợ các mục không hợp lệ. Một cặp (y, k) được đảm bảo tồn tại cho giá trị đầu vào x .
  • Đây là , vì vậy câu trả lời ngắn nhất bằng byte sẽ thắng!

Các trường hợp thử nghiệm

     3 -->     1
     5 -->     1
     6 -->     2
     9 -->     7
    10 -->     2
    23 -->    13
    85 -->     1
   549 -->   161
   960 -->    64
  1023 -->   341
  1155 -->   213
  1542 -->     2
  9999 -->  2819
 57308 --> 19124
 57311 -->   223
983055 -->     1

3
OEIS liên quan: A048274 là chuỗia(n) = g(n)
Giuseppe

Câu trả lời:


5

Java 8, 68 57 53 52 byte

n->{for(int i=0;i<n;)i-=(i*2^i)==n?n=i:-1;return n;}

-5 byte nhờ @ OlivierGrégoire .

Hãy thử trực tuyến.

Giải trình:

n->{                 // Method with integer as both parameter and return-type
  for(int i=0;i<n;)  //  Loop `i` in the range (1,n)
    i-=(i*2^i)==n?   //   If `i*2` XOR-ed with `i` equals `n`
        n=i          //    Set `n` to `i`, and set `i` to 0 to reset the loop
       :             //   Else:
        -1;          //    Increase `i` by 1 to go to the next iteration
  return n;}         //  Return `n` after the entire loop

1
n->{for(int i=0;i<n;)i-=(i*2^i)==n?n=i:-1;return n;}(52 byte). Xin lỗi ^^ '
Olivier Grégoire

@ OlivierGrégoire Thậm chí thông minh hơn, cảm ơn!
Kevin Cruijssen

for(int i=0;n>i-=i+i^i^n?-1:n=i;);?
Tít

@Titus Tôi sợ rằng nó sẽ không hoạt động trong Java (mặc dù tôi đã sử dụng cách tiếp cận đó trong câu trả lời JavaScript lặp lại của mình ). Trong Java i+i^i^n?không phải là boolean, do đó, nó thậm chí sẽ không biên dịch. Ngoài ra, n>i-=...sẽ cần dấu ngoặc đơn ( n>(i-=...)) và n=ikhông được phép trong mệnh đề khác của mệnh đề-if, chỉ trong mệnh đề if (điều cuối cùng này tôi không biết tại sao, nhưng đó là điều không may trong Java ).
Kevin Cruijssen

1
@KevinCruijssen "và n=ikhông được phép trong mệnh đề khác của ternary-if". Bởi vì Java sẽ phân tích nó như (i-=(i*2^i)!=n?-1:n)=ilà bất hợp pháp.
Olivier Grégoire


3

JavaScript, 53 byte

f=x=>(i=0,y=(G=x=>x&&(i^=x&1)+2*G(x>>1))(x),i?x:f(y))

Gg^-1, được đặt ithành0 nếu thành công, được đặt ithành 1nếu thất bại.


1
Đây là cách tiếp cận tôi đã cố gắng sử dụng mặc dù tôi đã đưa ra phiên bản 50 byte : f=n=>(g=n=>n<2?0/!n:n%2+2*g(n/2^n%2))(n)?f(g(n)):n. Đáng buồn là cách tiếp cận nhàm chán ngắn hơn 12 byte.
Neil

3

Pyth , 13 12 10 byte

Đã lưu 1 byte nhờ @MrXcoder và thêm 2 byte theo đề xuất của họ

fqQ.W<HQxy

Dùng thử trực tuyến

Giải trình:

fqQ.W<HQxyZZT   Implicit: Q=eval(input()), trailing ZZT inferred

f               Return the first T in [1,2,3...] where the following is truthy
   .W       T     Functional while - loop until condition is true, starting value T
     <HQ            Condition: continue while iteration value (H) less than input
        xyZZ        Body: xor iteration value (Z) with double (y) iteration value (Z)
 qQ               Is the result of the above equal to input?

1
Bạn có thể thả dấu Ttrong 12 byte.
Ông Xcoder

3

R , 73 65 byte

f=function(x){for(i in 1:x)if(x==bitwXor(i,i*2)){i=f(i);break};i}

Hãy thử trực tuyến!

Cảm ơn rất nhiều Giuseppe (-8) do các tinh chỉnh của bạn, vì vậy đơn giản nhưng rất hiệu quả


1
trái ngược với câu trả lời trước đó của bạn, bởi vì hàm này là đệ quy, bạn không cần f=vì hàm này cần phải được ràng buộc fđể hoạt động đúng. Điều đó đang được nói, công việc tốt, và lấy +1 từ tôi!
Giuseppe

2
bạn cũng có thể thực hiện một số trò đùa lại logic của mình và nhận được tới 65 byte
Giuseppe



2

C (gcc) , 57 56 55 51 byte

  • Đã lưu một byte nhờ vào trần nhà ; !=-.
  • Đã lưu một byte năm byte nhờ Rogem ; sử dụng các biểu thức ternary và quirks gcc.
X(O,R){for(R=1;R;O=R?R:O)for(R=O;--R&&(R^2*R)-O;);}

Hãy thử trực tuyến!


1
+1 choX(O,R)
JayCe

@ceilingcat Đề nghị tốt, cảm ơn.
Jonathan Frech

for(R=1;R;O=R?R:O)tiết kiệm một byte.

R=O;cuối cùng dường như là không cần thiết, giúp bạn tiết kiệm thêm 4 byte.

@Rogem Có vẻ là, cảm ơn.
Jonathan Frech

2

Z80Golf , 22 byte

00000000: 1600 1803 4216 007a b830 097a 82aa b828  ....B..z.0.z...(
00000010: f314 18f3 78c9                           ....x.

Câu trả lời Java của cảng @ KevinCruijssen

Ví dụ với đầu vào của 9-Hãy thử trực tuyến!

Ví dụ với đầu vào của 85-Hãy thử trực tuyến!

Hội,, tổ hợp:

;d=loop counter
;b=input and output
f:
	ld d,0
	jr loop
	begin:
	ld b,d
	ld d,0
	loop:
		ld a,d
		cp b
		jr nc,end	; if d==b end
		ld a,d
		add d		; mul by 2
		xor d
		cp b
		jr z,begin	; if (d*2)^d==b set b to d
		inc d
		jr loop
	end:
	ld a,b
	ret

Ví dụ lắp ráp để gọi hàm và in kết quả:

ld b,9 ; input to the function, in this case 9
call f
add 30h ; ASCII char '0'
call 8000h ; putchar
halt

Nếu bạn thực hiện abộ đếm vòng lặp thay vì d, thì bạn có thể thay thế các ld d,0hướng dẫn bằng xor acả hai lần, giúp tiết kiệm hai byte.
Misha Lavrov


1

JavaScript (Node.js), 48 45 38 byte

f=(n,i=0)=>i<n?i*2^i^n?f(n,i+1):f(i):n

-7 byte nhờ @Neil tạo phiên bản đệ quy của phiên bản lặp của tôi bên dưới. Không làm việc cho các trường hợp thử nghiệm lớn.

Hãy thử trực tuyến.


Phiên bản lặp 45 byte hoạt động cho tất cả các trường hợp thử nghiệm:

n=>{for(i=0;i<n;)i-=i*2^i^n?-1:n=i;return n;}

Cổng câu trả lời Java của tôi.
-3 byte nhờ @Arnauld .

Hãy thử trực tuyến.


1
Bạn có thể làm i-=i*2^i^n?-1:n=i(nhưng tiếc là không có trong Java).
Arnauld

@Arnauld Hình đã có một cái gì đó khả thi đối với boolean trong Java chỉ 1trong JS. Cảm ơn!
Kevin Cruijssen

1
38 byte được viết đệ quy (không hoạt động đối với các đầu vào lớn hơn):f=(n,i=0)=>i<n?i*2^i^n?f(n,i+1):f(i):n
Neil

1

Ruby , 39 byte

f=->x,y=x{y<1?x:x==y^y*2?f[y]:f[x,y-1]}

Hãy thử trực tuyến!

Như mong đợi cho phiên bản đệ quy, phàn nàn về "mức độ ngăn xếp quá sâu" trong các trường hợp thử nghiệm sau.


1

Thạch , 11 9 byte

BÄḂṛḄß$Ṫ?

Hãy thử trực tuyến!

Mẹo: Sử dụng hàm đệ quy thay vì vòng lặp.


Rất nhanh, không may thua cuộc với cách tiếp cận vũ phu.

Lưu ý rằng:

  • Với x> 0 , f (x)> x .
  • popcount (f (x)) là chẵn, trong đó popcount (n) là số bit được đặt trong n .
  • Nếu n có số chẵn, thì tồn tại x sao cho f (x) = n .
  • Đặt B (x) là biểu diễn nhị phân của x(l) là danh sách l với phần tử cuối cùng được loại bỏ. Khi đó B (x) là XOR tích lũy của (B (f (x))) .

Vì vậy, chúng tôi lặp đi lặp lại:

  • Tính toán biểu diễn nhị phân của nó ( B)
  • sau đó lấy XOR tích lũy (sử dụng ^\hoặc ÄḂ, chúng có tác dụng tương tự).
  • Kiểm tra xem ( ?) đuôi (phần tử cuối cùng) ( ) của XOR tích lũy có khác không (số lẻ)
    • Nếu vậy, chuyển đổi danh sách nhị phân trở lại thập phân và lặp lại.
    • Nếu không, trả về đầu vào ( ).


1

Forth (gforth) , 71 byte

: f 0 begin 2dup dup 2* xor = if nip 0 else 1+ then 2dup < until drop ;

Hãy thử trực tuyến!

Giải trình

0                 \ add an index variable to the top of the stack
begin             \ start an indefinite loop
  2dup            \ duplicate the top two stack items (n and i)
  dup 2* xor =    \ calculate i xor 2i and check if equal to n
  if nip 0        \ if equal, drop n (making i the new n) and use 0 as the new i
  else 1+         \ otherwise just increment i by 1
  then            \ end the if-statement
  2dup <          \ duplicate the top two stack items and check if n < i
until             \ if previous statement is true, end the loop
drop              \ drop i, leaving n on top of the stack

1

Perl 6 , 44 byte

{({first {($^a+^2*$a)==$_},^$_}...^!*).tail}

Thử nó

Mở rộng:

{  # bare block lambda with implicit parameter $_

  (
    # generate a sequence

    # no need to seed the sequence with $_, as the following block will
    # default to using the outer $_
    # $_, 

    { # parameter $_

      first
        {  # block with placeholder parameter $a

          ( $^a +^ 2 * $a ) # double (numeric) xor
          == $_             # is it equal to the previous value
        },

        ^$_  # Range up to and excluding the previous value ( 0..^$_ )
    }

    ...^  # keep doing that until: (and throw away last value)

    !*    # it doesn't return a trueish value

  ).tail  # return the last generated value
}


1

PHP, 49 byte

Dựa trên câu trả lời của Kevin Cruijssen.

for($x=$argn;$x>$i-=$i*2^$i^$x?-1:$x=$i;);echo$x;

Chạy như ống với -nrhoặc thử trực tuyến .


1

F #, 92 byte

let rec o i=
 let r=Seq.tryFind(fun x->x^^^x*2=i){1..i-1}
 if r.IsNone then i else o r.Value

Hãy thử trực tuyến!

Kiểm tra đệ quy thông qua các số từ 1 đến i-1. Nếu có một trận đấu, hãy kiểm tra số nhỏ hơn cho số đó. Nếu không có kết quả khớp, trả về số đầu vào.


1

JavaScript (Node.js) , 40 byte

f=n=>g(n)%2?n:f(g(n)/2)
g=x=>x&&x^g(x/2)

Hãy thử trực tuyến!

Cảm ơn Shaggy cho -1 byte.

Cổng trả lời Jelly của tôi .

Cuối cùng, có một ngôn ngữ mà cách tiếp cận này ngắn hơn (rất tiếc ). (Tôi đã thử Python và Java , nó không hoạt động)

Bất cứ ai có thể giải thích tại sao tôi có thể sử dụng /2thay vì >>1?


1
x/2hoạt động vì dòng chảy số học. Bất kỳ số IEEE 754 nào cuối cùng cũng sẽ được đánh giá là 0 khi chia cho 2 lần đủ. (Và phần thập phân chỉ bị bỏ qua khi XOR'd, vì vậy điều này không ảnh hưởng đến kết quả.)
Arnauld


@Shaggy Ngạc nhiên là nó hoạt động. Tôi biết nó hoạt động cho Python và Lua, v.v., nhưng không phải Javascript.
dùng202729

Việc falsetrả về ở lần lặp cuối cùng được mặc định 0bởi toán tử XOR bitwise.
Xù xì

@Shaggy Trong thực tế, không có falseliên quan . JS &&hành xử gần như giống hệt với Python / Lua and.
dùng202729

1

K (ngn / k) , 32 26 byte

{$[*|a:2!+\2\x;x;2/-1_a]}/

Hãy thử trực tuyến!

{ } là một hàm với đối số x

/ áp dụng nó cho đến khi hội tụ

$[ ; ; ] nếu-thì-khác

2\x chữ số nhị phân của x (điều này là cụ thể cho ngn / k)

+\ tổng một phần

2! mod 2

a: giao cho a

*|cuối cùng - đảo ngược ( |) và nhận đầu tiên (* )

nếu ở trên là 1, x sẽ được trả lại

nếu không thì:

-1_a bỏ yếu tố cuối cùng của a

2/ giải mã nhị phân


0

C, 62 byte

Dựa trên Java của Kevin Cruijssen:

int n(int j){for(int i=0;i<j;)i-=(i*2^i)==j?j=i:-1;return j;}

Để kiểm tra:

#include <stdio.h>
int n(int j);
#define p(i) printf("%6d --> %5d\n", i, n(i))
int main(void)
{
    p(3);
    p(5);
    p(6);
    p(9);
    p(10);
    p(23);
    p(85);
    p(549);
    p(960);
    p(1023);
    p(1155);
    p(1542);
    p(9999);
    p(57308);
    p(57311);
    p(983055);
}

Khi chạy, chương trình thử nghiệm xuất ra:

     3 -->     1
     5 -->     1
     6 -->     2
     9 -->     7
    10 -->     2
    23 -->    13
    85 -->     1
   549 -->   161
   960 -->    64
  1023 -->   341
  1155 -->   213
  1542 -->     2
  9999 -->  2819
 57308 --> 19124
 57311 -->   223
983055 -->     1

C, 54 byte

Chỉ hoạt động với C89 hoặc K & R C:

n(j){for(i=0;i<j;)i-=(i*2^i)==j?j=i:-1;return j;}


int n(int j){for(int i=0;j>i-=i*2^i^j?-1:j=i;);return j;}Do 57 byte này hoạt động?
Tít

0

Ngôn ngữ Wolfram (Mathicala) , 58 byte

Min[{#}//.x_:>Select[Range@#,MemberQ[x,#|BitXor[#,2#]]&]]&

Hãy thử trực tuyến!

Bắt đầu với một danh sách chỉ chứa đầu vào. Lặp lại thay thế danh sách bằng tất cả các số nguyên đã có trong nó hoặc ánh xạ vào danh sách đó bằng thao tác hai và xor. Sau đó //.nói để làm điều này cho đến khi đạt đến một điểm cố định. Câu trả lời là yếu tố ít nhất của kết quả.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.