Ben Cullen Numarası mıyım?


25

Bir Cullen Numarası, aşağıdaki formülü kullanarak üretilen dizide bulunan herhangi bir sayıdır:

C (n) = (n * 2 ^ n) +1.

Senin görevin:

Giriş alan ve girişin Cullen Numarası olup olmadığına bağlı olarak bir gerçeği / sahte değeri veren bir program veya işlev yazın.

Giriş:

0 ile 10 ^ 9 arasında negatif olmayan bir tam sayı (dahil).

Çıktı:

Girdinin Cullen Numarası olup olmadığını belirten bir truthy / falsy değeri.

Test Durumları:

Input:    Output:
1   --->  truthy
3   --->  truthy
5   --->  falsy
9   --->  truthy
12  --->  falsy
25  --->  truthy

puanlama:

Bu , yani bayt cinsinden en düşük puan kazanır.


1
N aralığı nedir ? Özellikle, 1 bir Cullen Sayısı mı?

3
@ ais523 göre OEIS , öyle. n0 tabanlı görünüyor.
steenbergh

Yeterince adil. Sadece benim Jelly cevap bir sahibi olup olmayacağını bilmemiz gereken veya Ronun içinde :-)


Umm, en aşağıya ne oldu?
Gryphon - Monica

Yanıtlar:



16

x86_64 makine kodu ( Sistem V ABI ), 28 27 bayt

@Cody Gray sayesinde -1 bayt, teşekkürler!

Sabit zamanlı bir algoritma!

_cullen:
   0:   0f bd cf    bsrl    %edi, %ecx
   3:   0f bd c1    bsrl    %ecx, %eax
   6:   89 ca       movl    %ecx, %edx
   8:   29 c2       subl    %eax, %edx
   a:   0f bd c2    bsrl    %edx, %eax
   d:   29 c1       subl    %eax, %ecx
   f:   d3 e1       shll    %cl, %ecx
  11:   ff c1       incl    %ecx
  13:   31 c0       xorl    %eax, %eax
  15:   39 f9       cmpl    %edi, %ecx
  17:   0f 94 c0    sete    %al
  1a:   c3          retq

Açıklama:

Let y bir tamsayı ve x=y*2^y + 1. Bu y + log2(y) = log2(x-1)yüzden günlükleri alıyoruz y=log2(x-1)-log2(y). Y değerini geri takarak anlıyoruz y=log2(x-1)-log2(log2(x-1)-log2(y)). Bunu bir kez daha yaparak elde ederiz y=log2(x-1)-log2[log2(x-1)-log2(log2(x-1)-log2(log2(x-1)-log2(y)))].

Son terimleri kaldıralım (sırası log2(log2(log2(log2(x))))ile güvenli olmalı!) Ve şunu kabul x-1≈xedelim: y≈log2(x)-log2[log2(x)-log2(log2(x))]

Şimdi, f(n) = floor(log2(n))işte y, tam olarak şu şekilde alınabileceği manuel olarak doğrulanabilir :, y <26y=f(x)-f[f(x)-f(f(x))] için ve böylece meydan okuma (1) tarafından belirtildiği gibi x x 10 ^ 9 .

Daha sonra algoritma basitçe x verilen y bilgisayarını içerir ve x == y * 2 ^ y + 1 olduğunu doğrulayın . Hile yani basit bir şekilde uygulanabilir ilk 1-bit dizini döndürür talimatı (bit tarama tersi), N , ve olduğu gibi .f(n)bsry*2^yy << y

Detaylı kod:

_cullen:                                 ; int cullen(int x) {
   0:   0f bd cf    bsrl    %edi, %ecx   ;  int fx = f(x);
   3:   0f bd c1    bsrl    %ecx, %eax   ;  int ffx = f(f(x));
   6:   89 ca       movl    %ecx, %edx   
   8:   29 c2       subl    %eax, %edx   ;  int a = fx - ffx;
   a:   0f bd c2    bsrl    %edx, %eax   ;  int ffxffx = f(a);
   d:   29 c1       subl    %eax, %ecx   ;  int y = fx - ffxffx;
   f:   d3 e1       shll    %cl, %ecx    ;  int x_ = y<<y;
  11:   ff c1       incl    %ecx         ;  x_++;
  13:   31 c0       xorl    %eax, %eax
  15:   39 f9       cmpl    %edi, %ecx
  17:   0f 94 c0    sete    %al
  1a:   c3          retq                 ;  return (x_ == x);
                                         ; }

(1) Aslında, bu eşitlik , 50000'e kadar olan y değerleri için geçerli görünmektedir .


4
Bunun şimdiye kadarki meydan okuma için en ilginç kod olarak nitelendirildiğinden eminim. +1
Gryphon - Monica

1
Ön XORing , 1 byte tasarruf eaxetmenizi önler movzbl. cmplElbette önce XOR'u yapmanız gerekecekti, bu yüzden tabii ki bayraklara dokunmuyor, ama bu tamamen iyi çünkü ondan sonraki hiçbir şey bağlı değil eax. Veya, yalnızca yöntemin bir Boolean döndürdüğüne, sadece 8 bitte karar verebilirsiniz, bu da 3 baytın tümünü kurtarır!
Cody Gray

Teşekkürler çok :), Nitekim @CodyGray
yoann

7

Jöle , 7 6 bayt

Ḷæ«`i’

Çevrimiçi deneyin!

Komut satırı argümanı olarak girdi alır. Cullen numarasını C (verilirse , n ), çıkışlar , n + 1 (jöle truthy, sıfırdan farklı, tam sayıdır, biz bu sahip olduğu not N girişi bir tam sayı olduğu, çünkü ≥0 ve Cullen numaraları negatif ile n tam sayılar asla) . Cullen olmayan bir sayı verilirse, Jelly'de falsey olan 0 değerini döndürür.

açıklama

Ḷæ«`i’
Ḷ        Form a range from 0 to (the input minus 1)
 æ«      Left-shift each element in the range by 
   `       itself
    i’   Look for (the input minus 1) in the resulting array

Temel olarak, bir eksi bir Cullen sayıları dizisi oluşturur, sonra içindeki eksi bir girişi arayın. Girdi bir Cullen numarası ise, onu bulacağız, aksi halde bulamayacağız. C ( n ) her zaman n'den büyük olduğundan , dizinin girdiye ulaşmak için yeterince uzun olduğunu unutmayın .


7

JavaScript (ES6), 37 35 bayt

Neil sayesinde 2 bayt kaydedildi

f=(n,k,x=k<<k^1)=>x<n?f(n,-~k):x==n

gösteri


Çalışıyor x<n?f(n,k+1):x==nmu
Neil

@Neil Kesinlikle öyle. :-)
Arnauld

Neden ~ k çalışıyor, k + 1 görüşmeyi aşırı yüklüyor?
trlkly

@ trlkly Temel olarak, undefined+1===NaNama -~undefined===1. Bununla ilgili daha fazla bilgiyi burada bulabilirsiniz .
Arnauld,


3

Ohm , 8 bayt

@Dº*≥Dlε

Çevrimiçi deneyin!

           Implicit input
@          Range [1,...,Input]
 D         Duplicate
  º        2^n each element
   *       Multiply those two array
    ≥      Increment everything (now I have an array of all Cullen Numbers)
     Dl    Push array length (= get input again, can't get again implicitly or using a function because it would be a string so I'd waste a byte again)
       ε   Is input in array?


3

05AB1E , 7 bayt

ÝDo*¹<å

Çevrimiçi deneyin!

Açıklama:

ÝDo*¹<å Example input: 9. Stack: [9]
Ý       Range 0-input. Stack: [[0,1,2,3,4,5,6,7,8,9]]
 D      Duplicate. Stack: [[0,1,2,3,4,5,6,7,8,9],[0,1,2,3,4,5,6,7,8,9]]
  o     2** each item in the list. Stack: [[0,1,2,3,4,5,6,7,8,9], [1,2,4,8,16,32,64,128,256,512]]
   *    Multiply the two lists. Stack: [[0, 2, 8, 24, 64, 160, 384, 896, 2048, 4608]]
    ¹   Push input again. Stack: [[0, 2, 8, 24, 64, 160, 384, 896, 2048, 4608],9]
     <  Decrement. Stack: [[0, 2, 8, 24, 64, 160, 384, 896, 2048, 4608],8]
      å Is the first item of the stack in the second item? Stack: [1]
        Implicit print.

3

R , 53 51 46 bayt

pryr::f(x%in%lapply(0:x,function(y)(y*2^y+1)))

Anonim işlev x[0, x] 'daki n (C) dizisinde n'nin üretilip üretilmediğini kontrol eder .

Giuseppe tarafından oynanan 3 bayt.

Çevrimiçi deneyin!


x%in%...yerine kullanın any(x==...); Bu size 4 byte bırakacağım
Giuseppe

Yani lapply, sadece vektörü kontrol ederek bunu değiştirerek golf scanoynarsam ve işlev argümanları yerine kullanırsam - @giuseppe 'in cevabını alıyorum. Ayrı gönderdiğiniz için teşekkürler, böylece neyin eksik olduğunu görebiliyorum - genellikle kaybedmeme rağmen kendi başıma bir şeyler deneyerek daha fazla şey öğreniyorum.
BLT

3

C, C ++, Java, C #, D: 70 bayt

Tüm bu diller arasındaki benzerlikler nedeniyle, bu kod her biri için işe yarar.

int c(int n){for(int i=0;i<30;++i)if((1<<i)*i+1==n)return 1;return 0;}

Bu sefer optimize edilmiş D versiyonunu göndereceğim, bazı güzel D-püf noktaları kullanılabilir.
Zacharý,

Öner i=30;i--;)if(i<<i==n-1)yerinei=0;i<30;++i)if((1<<i)*i+1==n)
ceilingcat



2

R , 26 bayt

a=0:26;scan()%in%(1+a*2^a)

Çevrimiçi deneyin!

Diğer R cevabından biraz farklı bir yaklaşım ; okur stdinbiz sadece kontrol etmek zorunda ve giriş 0 ve ^ 9 ile 10 arasında olması sağlanır beri n0 ile 26 arasındadır.


Asla hatırlamıyorum scan(). İyi iş.
BLT

2

APL (Dyalog) , 9 bayt

N = 1 durumunun üstesinden ⎕IO←0gelmek için, çoğu sistemde hangisinin varsayılan olacağını gerektirir .

⊢∊1+⍳×2*⍳

Çevrimiçi deneyin!

 [is] n (bağımsız değişken)

 üyesi

1 bir

+ artı

i ntegers 0 ... ( n -1)

× zamanlar

2 iki

* gücüne

i ntegers 0 ... ( n -1)


Yani, "birçok sistemde varsayılan" sadece var olduğu anlamına mı geliyor ?
Zacharý,

@ Zacharý Evet, ⎕IO←0standart dışı olarak adlandırmak yanlıştır , çünkü çoğu zaman her zaman böyle bir spesifikasyon gerektirmeden, her zaman böyle bir şey yapmıştır.
Adám

İyi. Şansım varsa bu numarayı kesinlikle MY’de kullanacağım (ve MY’de 0 olmayan ve 1 endeks kökenli olmayan kaynaklar olabilir).
Zacharý,

@ Zacharý Bu, bu değerlerin varsayılan olduğu gerçek bir kurulum tabanı / sürümleri gerektirmez mi? Örneğin SAX ve ngn ⎕IO←0.
Adám

Evet, sanırım olur. Ve MY'nin üç iotası var, bu yüzden bunun bir daha kullanılmayacağını düşünüyorum.
Zacharý

2

Python 2,32 bayt

[n<<n|1for n in range(26)].count

Çevrimiçi deneyin!

Cullen numaralarının listesini oluşturur 10^9, ardından girişin içinde kaç kez göründüğünü sayar. Vincent n<<n|1yerine (n<<n)+12 bayt tasarruf yerine işaret için teşekkürler .


İki byte'ı n<<n|1( n<<nhatta);) kullanarak tasarruf edebilirsiniz
Vincent

Bu başarısız olur 838860801. İhtiyacınız var range(26)çünkü menzil kapsayıcı değil.
mbomb007

@ mbomb007 Teşekkürler. Bunu bir süredir yaptım ve hala aralıkların özel olduğunu unutma.
xnor

2

D, 65 bayt

Bu, @ HatsuPointerKun’un D’ye algoritması.

T c(T)(T n){for(T i;i<30;++i)if((1<<i)*i+1==n)return 1;return 0;}

Nasıl? (D belirli püf noktaları)

D'nin şablon sistemi, C ++ 'dan daha kısa ve türleri çıkartabilir. Ve D ayrıca değişkenleri beyan üzerine temerrüde sıfırlar.


1

Mathematica, 30 bayt

MemberQ[(r=Range@#-1)2^r+1,#]&

Girdi ve geri dönen olarak negatif olmayan tamsayı alarak Saf fonksiyon Trueya False. Girdi ise n, (r=Range@#-1)değişkeni rolacak şekilde ayarlar {0, 1, ..., n-1}ve sonra r2^r+1ilk nCullen sayılarını vektörel olarak hesaplar . MemberQ[...,#]daha sonra nlistenin bir elemanı olup olmadığını kontrol eder .



1

Excel VBA, 45 Bayt

Hücre [A1]ve çıkışlardan VBE anlık penceresine girdi alan anonim VBE acil pencere işlevi

Temiz bir modülde çalıştırılmalıdır ya da i, j değerleri, değerler arasında varsayılan 0 değerine sıfırlanmalıdır.

While j<[A1]:j=(i*2 ^ i)+1:i=i+1:Wend:?j=[A1]

Giriş çıkış

VBE hemen penceresinde görüldüğü gibi G / Ç

[A1]=25
While j<[A1]:j=(i*2 ^ i)+1:i=i+1:Wend:?j=[A1]
True

[A1]=1: i=0:j=0 ''# clearing module values
While j<[A1]:j=(i*2 ^ i)+1:i=i+1:Wend:?j=[A1]
True    

[A1]=5: i=0:j=0 ''# clearing module values
While j<[A1]:j=(i*2 ^ i)+1:i=i+1:Wend:?j=[A1]
False 

1

Swi-Prolog, 69 bayt

f(X)X = I * 2 ^ I + 1 olan bir I değerini bulabilirse başarılı olur. Aralık ipucu yığın boşluğunun bitmesini önler, ancak soru özelliğinde 10 ^ 9'a kadar Cullen sayıları aralığı için yeterlidir.

:-use_module(library(clpfd)).
f(X):-I in 0..30,X#=I*2^I+1,label([I]).

Örneğin

f(838860801).
true

1

cQuents , 9 bayt

$0?1+$2^$

Çevrimiçi deneyin!

açıklama

$0           n is 0-indexed
  ?          Mode query. Given input n, output true/false for if n is in the sequence.
   1+$2^$    Each item in the sequence equals `1+index*2^index`

1

TI-BASIC, 17 bayt

max(Ans=seq(X2^X+1,X,0,25

açıklama

seq(X2^X+1,X,0,25 Generate a list of Cullen numbers in the range
Ans=              Compare the input to each element in the list, returning a list of 0 or 1
max(              Take the maximum of the list, which is 1 if any element matched

Buna bir açıklama eklemek isteyebilirsiniz.
Gryphon - Monica

Tamam, bahşiş için teşekkürler.
calc84maniac 0 '12'de

Bu işe yarar, ancak komut tarafından bir açıklama genellikle en fazla oy toplamanıza yardımcı olur. Bu cevabın açıklaması gibi bir şey yapmayı tavsiye ederim . Neden birileri görevinizi reddettiğini bilmiyorum. Bu fikir genellikle göz ardı edilse de, genellikle bunu yaparken yorum bırakmanız genel bir nezakettir.
Gryphon - Monica

Rica ederim. Siteye ilk katıldığımda, insanların bana bu tür şeyler söylediğini hatırlıyorum Sadece iyilikten geçiyorum.
Gryphon - Monica

0

QBIC , 24 bayt

[0,:|~a*(2^a)+1=b|_Xq}?0

açıklama

[0,:|           FOR a = 0 to b (input from cmd line)
~a*(2^a)+1=b    IF calculating this a results in b
|_Xq            THEN quit, printing 1
}               NEXT a
?0              We haven't quit early, so print 0 and end.

0

k , 19 bayt

{&1=x-{x**/x#2}'!x}

Çevrimiçi deneyin. Gerçek, içinde bir sayı bulunan bir dizidir: ,3veya ,0et cetera. Falsey boş bir dizidir: ()veya !0tercümanınıza bağlı olarak.



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.