Kiểm tra xem một số nguyên có phải là lũy thừa 2 không mà không sử dụng +, - phép toán [đã đóng]


30

Viết chương trình kiểm tra xem số nguyên có lũy thừa bằng 2 không.


Đầu vào mẫu:

8

Đầu ra mẫu:

Yes

Đầu vào mẫu:

10

Đầu ra mẫu:

No

Quy tắc:

  • Đừng sử dụng +, -hoạt động.

  • Sử dụng một số loại luồng đầu vào để lấy số. Đầu vào không được cho là ban đầu được lưu trữ trong một biến.

  • Mã ngắn nhất (tính bằng byte) sẽ thắng.

Bạn có thể sử dụng bất kỳ phản hồi trung thực / giả mạo (ví dụ: true/ false). Bạn có thể cho rằng số đầu vào lớn hơn 0.


1
Có phải nó cũng được phép xuất "đúng" thay vì "có" và "sai" thay vì "không"?
Chương trìnhFOX

2
Có, bạn có thể sử dụng bất kỳ phản ứng tích cực / tiêu cực. Câu hỏi được cập nhật.
gthacoder

1
Các predchức năng, khi áp dụng cho một số nguyên n, lợi nhuận n - 1. Có chức năng như thế này, đó là cải trang mỏng xung quanh các nhà điều hành bị cấm, cũng bị cấm?
Wayne Conrad

1
@Wayne giống như golfscript ), hoặc hầu hết các ngôn ngữ dựa trên c ' --.
Doorknob

2
Tôi biết hiện tại chúng tôi sẽ có 3 năm trong tương lai, nhưng "toán tử +/-" không thể quan sát được, hoặc ít được xác định là yếu nhất.
ATaco

Câu trả lời:


13

GolfScript, 6 ký tự, không giảm

~.3/&!

Đây là một giải pháp không sử dụng x & (x-1)phương thức này dưới mọi hình thức. Nó sử dụng x & (x/3)thay thế. ;-) Đầu ra 0nếu sai, 1nếu đúng.

Giải trình:

  • ~ tránh chuỗi đầu vào để biến nó thành một số,
  • .nhân đôi nó (cho lần sau &),
  • 3/ chia nó cho ba (cắt giảm),
  • & tính toán bitwise AND của giá trị được chia với giá trị gốc, giá trị này sẽ bằng 0 khi và chỉ khi đầu vào bằng 0 hoặc lũy thừa của hai (tức là có nhiều nhất một tập bit) và
  • ! logic phủ định điều này, ánh xạ 0 đến một và tất cả các giá trị khác thành 0.

Ghi chú:

  • Theo các quy tắc được làm rõ, số 0 không phải là đầu vào hợp lệ , vì vậy mã này vẫn ổn, mặc dù nó xuất ra 1nếu đầu vào bằng không.

  • Nếu toán tử phân rã GolfScript (được cho phép, thì giải pháp 5 ký tự ~.(&! được đăng bởi aditsu là đủ. Tuy nhiên, nó dường như đi ngược lại tinh thần của các quy tắc , nếu không phải là bức thư.

  • Tôi đã nghĩ ra x & (x/3)mánh khóe nhiều năm trước trong danh sách gửi thư của Fun With Perl. (Tôi chắc chắn tôi không phải là người đầu tiên phát hiện ra nó, nhưng tôi đã (phát minh lại) nó một cách độc lập.) Đây là một liên kết đến bài viết gốc , bao gồm một bằng chứng rằng nó thực sự hoạt động.


Tôi nghĩ rằng nó thực sự là một chút ngớ ngẩn, golfscript cho phép một người viết giải pháp chính xác mà OP muốn loại trừ mà không thực sự phá vỡ các quy tắc.
Tim Seguine

1
@Tim: OK, đây là một cái không giảm, sau đó. ;)
Ilmari Karonen

làm thế nào điều này có thể làm việc? Ví dụ 7/3 = 2 (0010), vì vậy 7 & 2 = 0111 & 0010 = 0010rõ ràng bit cuối cùng không phải là 1
phuclv

@ LưuViênPhúc: Không, nhưng bit thứ hai là. Hãy thử chia dài 3 lần trong nhị phân và khá rõ ràng tại sao điều này luôn xảy ra nếu cổ tức có nhiều hơn một bit được đặt.
Ilmari Karonen

ah Tôi đã đọc sai điều này với "chia hết cho 2"
phuclv

15

APL (7)

Vâng, đó là 7 byte . Giả sử hiện tại tôi đang sử dụng IBM codepage 907 thay vì Unicode và sau đó mỗi ký tự là một byte :)

0=1|2⍟⎕

I E 0 = mod(log(input(),2),1)


Chỉ cần tự hỏi, điều gì xảy ra nếu bạn cho nó 0 hoặc một số âm?
aditsu

@aditsu Tôi không biết mod 1 vô cực là gì, nhưng chắc chắn không nên bằng không.
Tim Seguine

1
@TimSeguine Mathematica cho tôi Indeterminatekhi tôi thử điều đó.
LegionMammal978

7

GolfScript, 11 (cho 1 (đúng) và 0 (sai))

.,{2\?}%?0>

Đặt số trên ngăn xếp và sau đó chạy.

GolfScript, 22 (cho Có / Không)

.,{2\?}%?0>'Yes''No'if

Tôi thích cách chuyển đổi 1/ 0thành Yes/ Nolấy nhiều mã như chính thử thách: D

Cảnh báo: TUYỆT VỜI không hiệu quả;) Nó hoạt động tốt với các số lên tới 10000, nhưng một khi bạn đạt được mức cao đó, bạn bắt đầu nhận thấy độ trễ nhẹ.

Giải trình:

  • .,: biến nthành n 0..n( .trùng lặp, ,phạm vi 0..n)
  • {2\?}: với sức mạnh của 2
  • %: ánh xạ "sức mạnh của 2" trên "0..n" để nó trở thành n [1 2 4 8 16 ...]
  • ?0>: kiểm tra xem mảng có chứa số không (0 lớn hơn chỉ mục)

1
Ngắn hơn 1 byte cho Có / Không : .,{2\?}%?0<'YesNo'3/=; Ngoài ra, tôi nghĩ rằng bạn đang gian lận bằng cách yêu cầu "Đặt số trên ngăn xếp", bạn nên bắt đầu bằng a ~.
aditsu

1
Thất bại vào ngày 1, tức là 2 ^ 0
Joachim Isaksson

6

Toán học 28

Numerator[Input[]~Log~2]==1

Đối với quyền hạn số nguyên là 2, tử số của nhật ký cơ sở 2 sẽ là 1 (có nghĩa là nhật ký là một phần đơn vị).

Ở đây chúng tôi sửa đổi chức năng một chút để hiển thị đầu vào giả định. Chúng tôi sử dụng #thay thế Input[]và thêm &để xác định một hàm thuần túy. Nó trả về cùng một câu trả lời sẽ được trả về nếu người dùng nhập số vào hàm trên.

    Numerator[#~Log~2] == 1 &[1024]
    Numerator[#~Log~2] == 1 &[17]

Đúng
sai

Kiểm tra một số số tại một thời điểm.

    Numerator[#~Log~2] == 1 &&/@{64,8,7,0}

{Đúng, Đúng, Sai, Sai}


4

Perl 6 (17 ký tự)

say get.log(2)%%1

Chương trình này nhận một dòng từ gethàm STDIN , tính toán logarit với cơ sở 2 trên nó ( log(2)) và kiểm tra xem kết quả có chia cho 1 ( %%1, trong đó %%được chia cho toán tử). Không ngắn như giải pháp GolfScript, nhưng tôi thấy điều này có thể chấp nhận được (dù sao GolfScript cũng thắng mọi thứ), nhưng nhanh hơn (ngay cả khi xem xét rằng Perl 6 đang chậm).

~ $ perl6 -e 'say get.log(2)%%1'
256
True
~ $ perl6 -e 'say get.log(2)%%1'
255
False

2
Lý do +-bị cấm đối với thử thách này là bởi vì nếu x & (x - 1)bằng 0, thì đó xlà sức mạnh của 2.
Chương trìnhFOX

@ProgramFOX: Tôi hiểu. Thủ thuật thú vị.
Konrad Borowski

1
@ProgramFOX Nhưng x&~(~0*x)vẫn hoạt động. Đó chỉ dài hơn 2 ký tự.
orlp

4

Octave ( 15 23)

EDIT: Cập nhật do yêu cầu đầu vào của người dùng;

~mod(log2(input('')),1)

Cho phép người dùng nhập giá trị và xuất 1 thành true, 0 cho false.

Đã thử nghiệm ở Octave, cũng nên làm việc trong Matlab.


Cũng hoạt động trong Matlab :)
jub0bs

4

R, 13 11

Dựa trên giải pháp Perl. Trả về FALSEhoặc TRUE.

!log2(i)%%1

Tham số iđại diện cho biến đầu vào.

Một phiên bản thay thế với đầu vào của người dùng:

!log2(scan())%%1

4

GolfScript, 5

Đầu ra 1 cho đúng, 0 cho sai. Dựa trên ý tưởng của user3142747:

~.(&!

Lưu ý: (là giảm, hy vọng nó không được tính là -:)
Nếu có (và ý kiến ​​của OP cho thấy có thể), thì vui lòng tham khảo giải pháp của Ilmari Karonen thay thế.
Đối với đầu ra Y / N, nối 'NY'1/=vào cuối (thêm 7 byte).


4

Con trăn, 31 tuổi

print 3>bin(input()).rfind('1')

31 nếu bạn làmbin(input()).rfind('1')<3
Blender

@Blender Phát hiện tốt. Tôi đã sử dụng 2==bởi vì tôi nghĩ rằng nó cũng hoạt động cho các số không cố ý. Điều đó rõ ràng là không bắt buộc bởi các quy tắc, vì vậy ...
boothby

1
+1. Tôi sẽ đăng print bin(input()).count('1')<2tổng cộng 31 ký tự, nhưng nó quá giống với bạn.
Steven Rumbalski

4

C, 48

main(x){scanf("%i",&x);puts(x&~(x*~0)?"F":"T");}

Có thể ngắn hơn nếu phủ định unary được cho phép, dài hơn nếu hằng số âm không được phép. Giả sử bổ sung của hai.
orlp

*có quyền ưu tiên cao hơn nhị phân &, bạn không cần parens. Và nếu giá trị trả lại được chấp nhận (chỉ cần hỏi) exit(x&x*-1)sẽ ngắn hơn nhiều.
Kevin

Có một -: x*-1.
klingt.net

@ klingt.net có, nhưng đó là một phần của hằng số. Về mặt kỹ thuật, như được nói đến bây giờ, chỉ có các nhà điều hành -bị cấm.
Kevin

1
@ klingt.net Thay thế nó bằng một phiên bản không sử dụng dấu hiệu.
orlp

4

Tôi quyết định sử dụng một cách tiếp cận khác, dựa trên tổng số dân hoặc tổng số ngang (số lượng 1 bit). Ý tưởng là tất cả các quyền hạn của hai có chính xác một 1bit, và không có số nào khác. Tôi đã thêm một phiên bản JavaScript vì tôi thấy nó thú vị, mặc dù nó chắc chắn sẽ không chiến thắng bất kỳ cuộc thi golf nào.

J, 14 15 ký tự (đầu ra 0 hoặc 1)

1=##~#:".1!:1]1

JavaScript, 76 ký tự (đầu ra đúng hoặc sai)

alert((~~prompt()).toString(2).split("").map(Number).filter(Boolean).length)

Điều này sử dụng bổ sung, được ngăn chặn bởi các thách thức.
FUZxxl 14/03/2015

Huh. Tôi không biết tôi đã nghĩ gì khi tôi viết điều này ... Tôi đã sửa nó ngay bây giờ để nó thực sự tuân theo các quy tắc.
FireFly

4

Clip , 9 8 7

!%lnxWO

Đọc một số từ stdin.

Giải trình:

Để bắt đầu, Z= 0, W= 2O= 1. Điều này cho phép đặt WOcạnh nhau, trong khi sử dụng 21sẽ được hiểu là số 21 mà không có khoảng trắng (ký tự phụ không mong muốn). Trong Clip, hàm modulo ( %) hoạt động trên các số nguyên không, vì vậy, để tìm ra nếu một số giá trị vlà số nguyên, bạn kiểm tra xem vmod 1 = 0. Sử dụng cú pháp Clip, điều này được viết là =0%v1. Tuy nhiên, vì booleans được lưu trữ dưới dạng 1(hoặc bất cứ thứ gì khác) và 0, kiểm tra xem một cái gì đó có bằng không 0chỉ là 'không'. Đối với điều này, Clip có !toán tử. Trong mã của tôi, vlnx2. xlà một đầu vào từ stdin,nchuyển đổi một chuỗi thành một số và lablà cơ sở nhật ký bcủa a. Do đó, chương trình dịch (dễ đọc hơn) sang 0 = ((log base 2 of parseInt(readLine)) mod 1).

Ví dụ:

8

đầu ra

1

10

đầu ra

0

Chỉnh sửa 1: thay thế 0, 12với Z, OW.

Chỉnh sửa 2: thay thế =Zbằng !.

Cũng thế:

Bình thường , 5

Nén phiên bản Clip hơn nữa, vì Pyth có Q cho đầu vào đã được đánh giá và hàm log2 (a) thay vì chỉ nhật ký chung (a, b).

!%lQ1

3

Javascript (37)

a=prompt();while(a>1)a/=2;alert(a==1)

Kịch bản đơn giản chỉ cần chia 2 lần và kiểm tra phần còn lại.


1
cùng một ý tưởng với một forvòng lặp (cũng là 37 ký tự)for(i=prompt();i>1;i/=2){}alert(i==1)
làm lạnh toán học

3

Toán học (21)

IntegerQ@Log2@Input[]

Không có đầu vào thì ngắn hơn một chút

IntegerQ@Log2[8]

Thật

IntegerQ@Log2[7]

Sai


⌊#⌋==#&@Log2@Input[]
alephalpha

1
@alephalpha Kết thúc bằng 24 byte cho các ký tự UTF-8. Một chương trình 21 byte khác là Log2@Input[]~Mod~1==0.
LegionMammal978

2

JavaScript, 41 40 ký tự

l=Math.log;alert(l(prompt())/l(2)%1==0);

Cách thức hoạt động: bạn lấy logarit ở cơ sở 2 bằng cách sử dụng l(prompt()) / l(2)và nếu kết quả đó modulo 1 bằng 0, thì đó là lũy thừa của 2.

Ví dụ: sau khi lấy logarit của 8 trên cơ sở 2, bạn nhận được 3. 3 modulo 1bằng 0, vì vậy điều này trả về đúng.

Sau khi lấy logarit của 7 trên cơ sở 2, bạn nhận được 2.807354922057604. 2.807354922057604 modulo 1bằng 0.807354922057604, vì vậy điều này trả về sai.


Bạn không cần phải nhập dữ liệu vào một số; Math.logsẽ thực hiện điều đó : "Mỗi hàm đối tượng Math sau đây áp dụng toán tử trừu tượng ToNumber cho từng đối số của nó ..."
apsillers

Nó không bị thiếu chính xác số?
Mark Jeronimus

@MarkJeronimus: Tôi thực sự không biết. Có thể là vậy, nhưng tôi chưa gặp phải một kết quả không chính xác.
Chương trìnhFOX

2

JavaScript, 35

Hoạt động cho byte.

alert((+prompt()).toString(2)%9==1)

Phiên bản 46 ký tự , Hoạt động cho số 16 bit.

x=(+prompt()).toString(2)%99;alert(x==1|x==10)

Thủ thuật hoạt động trong hầu hết các ngôn ngữ năng động.

Giải thích: Chuyển đổi số thành cơ sở 2, giải thích chuỗi đó là cơ sở 10, thực hiện modulo 9 để lấy tổng chữ số, phải là 1.


Thế còn 0x2ff, trong cơ sở 2 là 1111111111gì?
Peter Taylor

@PeterTaylor Bạn đã đúng, đã sửa
sao chép

Vì vậy, điều thực sự bạn đang làm là kiểm tra modulo 10 mà không có phần còn lại, nhưng bạn đã sử dụng 9 để cạo một ký tự mã của mình , +1!
làm lạnh toán học

Đây là một sự gian lận nhưng một phương pháp khác:alert(!(Number.MAX_VALUE%prompt()))
Diêm vương


2

trăn 3, 38

print(1==bin(int(input())).count('1'))

trăn, 32

Tuy nhiên, mã không hoạt động trong mọi phiên bản.

print 1==bin(input()).count('1')

Lưu ý rằng giải pháp cũng hoạt động với 0 (in Sai).


Ủng hộ vì đây là giải pháp của tôi.
Josh Caswell

1
Nếu bạn thay thế ==bằng &gì?
SimonT

@SimonT Điều này không đúng. Thay thế '==' bằng '&' sẽ in 1 cho mỗi số có số lẻ '1' trong biểu diễn nhị phân của nó. Kiểm tra ví dụ 7 = 111. Có 3 = 11 cái. Nó sẽ trả về 11 & 1 = 1.
Gari BN

2

Ruby - 17 ký tự (lần thử thứ tư)

p /.1/!~'%b'%gets

Điều tốt nhất hiện tại của tôi là sự hợp nhất câu trả lời của @ steenslag với câu trả lời của riêng tôi. Dưới đây là những nỗ lực trước đây của tôi.

Ruby - 19 ký tự (lần thử thứ ba)

p /10*1/!~'%b'%gets

Ruby - 22 ký tự (lần thử thứ hai)

p !('%b'%gets)[/10*1/]

Ruby - 24 ký tự (lần thử đầu tiên)

p !!('%b'%gets=~/^10*$/)

vẫn còn một dấu "+" trong chương trình của bạn
phuclv

Tôi biết. : - / Tôi đã yêu cầu làm rõ liệu '+' và '-' có bị nghiêm cấm hay không, hoặc liệu chúng có thể được sử dụng trong các bối cảnh khác ngoài phép cộng và phép trừ. Tôi đang trong quá trình viết lại bất kể
OI

Cải tiến tuyệt vời. Có vẻ như đó là kết quả Ruby tốt nhất cho đến nay. Tôi cập nhật bảng lãnh đạo trong văn bản câu hỏi.
gthacoder

@gthacoder Chỉ cần kết hợp regex của steenslag với định dạng nhị phân của tôi. Chắc chắn không thể lấy tất cả tín dụng.
OI

2

K / Kona ( 24 17)

d:{(+/(2_vs x))~1

Trả về 1 nếu đúng và 0 nếu sai. Bất kỳ lũy thừa nào của 2 đều có một bit bằng 1:

2_vs'_(2^'(!10))
(,1
1 0
1 0 0
1 0 0 0
1 0 0 0 0
1 0 0 0 0 0
1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0)

(điều này in ra tất cả các quyền hạn của 2 (từ 0 đến 9) ở dạng nhị phân)

Vì vậy, tôi tổng hợp tất cả các thành phần của biểu thức nhị phân xvà xem nếu nó bằng 1; nếu có thì x=2^nkhông, không.

... biết tôi có thể làm cho nó nhỏ hơn


@gthacoder: Tôi đã làm cho mã nhỏ hơn, hy vọng bạn có thể cập nhật cho bạn bài đăng chính để phản ánh điều này!
Kyle Kanos

Điều này không sử dụng bổ sung? Và không phải là câu hỏi, sai, cấm điều đó?
zgrep

2

C # (54 ký tự)

 Math.Log(int.Parse(Console.ReadLine()),2)%1==0?"Y":"N"

Tác vụ nêu rõ rằng đầu vào không được lưu trữ trong một biến, nên lấy từ luồng đầu vào của một loại nào đó (như stdin), ngoài ra, đây là mã golf , hãy thử rút ngắn mã của bạn một chút, ít nhất là bằng cách xóa khoảng trắng
mniip

Tôi nghĩ bạn chỉ có ý Int32, không phải ToInt32...
Chris

Ya ya. Cảm ơn đã chỉ ra Chris. Trước đó, nó là Convert.ToInt32 và tôi muốn đổi nó thành Int32.Pude để rút ngắn nó. : D
Merin Nakarmi

2
sử dụng intthay vì Int32cho 2 ký tự ít hơn.
Rik

2

Rebmu (9 ký tự)

z?MOl2A 1

Kiểm tra

>> rebmu/args [z?MOl2A 1] 7
== false

>> rebmu/args [z?MOl2A 1] 8 
== true

>> rebmu/args [z?MOl2A 1] 9 
== false

Rebmu là một phương ngữ hạn chế của Rebol. Mã về cơ bản là:

z? mo l2 a 1  ; zero? mod log-2 input 1

Thay thế

14 chars Vượt qua Rebmu không có bit 'bị ép' VÀ ~

z?AND~aTIddA 3

Trong Rebol:

zero? a & to-integer a / 3


1

Con trăn, 35

print bin(input()).strip('0')=='b1'

Không chỉ sử dụng các hoạt động +/-, mà bất kỳ hoạt động toán học nào ngoài việc chuyển đổi sang dạng nhị phân.

Những thứ khác (thú vị, nhưng không phải để cạnh tranh):

Tôi cũng có một phiên bản regrec (61) :

import re;print re.match(r'^0b10+$',bin(input())) is not None

(Thích ý tưởng, nhưng chức năng nhập và kết hợp làm cho nó quá dài)

phiên bản hoạt động bitwise đẹp, nhưng nhàm chán (31) :

x=input();print x and not x&~-x

(vâng, nó ngắn hơn, nhưng nó sử dụng ~ -x để giảm dần - hoạt động)


câu trả lời của boothby sử dụng cùng một ý tưởng như câu trả lời đầu tiên của tôi, nhưng ngắn hơn :(
Ivan Anishchuk

1

Con trăn 2.7 ( 30 29 39 37)

EDIT: Cập nhật do yêu cầu đầu vào của người dùng;

a=input()
while a>1:a/=2.
print a==1

Lực lượng vũ phu, cố gắng phân chia cho đến khi = 1 (thành công) hoặc <1 (thất bại)


1
not a%2có thể được viết là a%2==0. Cấp, điều này sẽ dài hơn trong nhiều ngôn ngữ, nhưng không phải Python.
Konrad Borowski

@xfix Cảm ơn, đã thử nghiệm và cập nhật.
Joachim Isaksson

1
hoặc thậm chí tốt hơn , a%2<1.
gian hàng

bạn có một khoảng 2.trắng sau khi xóa sẽ tiết kiệm một byte!
Keerthana Mitchhakaran

1

Con trăn (33)

print int(bin(input())[3:]or 0)<1

int(bin(input()*2)[3:])<1cũng hoạt động từ vỏ trăn chỉ với 25 ký tự.
gmatht


1

APL (12 cho 0/1, 27 cho có / không)

≠/A=2*0,ιA←⍞ 

hoặc, nếu chúng ta phải xuất văn bản:

3↑(3x≠/A=2*0,ιA←⍞)↓'YESNO '

Đọc trong A. Tạo một vectơ 0..A, rồi vectơ 2 0 ..2 A (vâng, đó là cách cần thiết hơn), sau đó một vectơ so sánh A với mỗi vectơ (kết quả là vectơ 0 và nhiều nhất một 1), sau đó xor rằng (không có toán tử xor trong APL, nhưng áp dụng cho booleans sẽ hoạt động như một.) Bây giờ chúng ta có 0 hoặc 1.

Để có CÓ hoặc KHÔNG: nhân 0 hoặc 1 với 3, bỏ số ký tự này từ 'YESNO', sau đó lấy 3 ký tự đầu tiên này.


1

C, 65 byte

main(k){scanf("%i",&k);while(k&&!(k%2))k/=2;puts(k==1?"T":"F");}

Bạn có thể cắt bỏ 5 ký tự bằng cách sử dụng main(k){..., dựa vào intkiểu gõ ngầm . Nó có thể là UB, nhưng đây là mã golf. KHÔNG BAO GIỜ sử dụng một cái gì đó như thế trong sản xuất, tất nhiên.
Kevin

1

Haskell ( 52 50)

k n=elem n$map(2^)[1..n]
main=interact$show.k.read
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.