Av Tüfeği Numaraları


45

Tüfek sayılar oldukça basit tanımı ancak bazı ilginç yapısıyla bir dizi vardır. Doğal sayılarla başla:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

Şimdi tüm sayıları 2'ye bölünebilen endekslerde al , onları çiftler halinde gruplandır ve sayıları her çiftte değiştir:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ...
   ^     ^     ^     ^      ^       ^       ^  
    <--->       <--->        <----->         <----
1, 4, 3, 2, 5, 8, 7, 6, 9, 12, 11, 10, 13, 16, ...

Şimdi aynısını 3 ile bölünebilen endekslerle yapın :

1, 4, 3, 2, 5, 8, 7, 6, 9, 12, 11, 10, 13, 16, ...
      ^        ^        ^           ^          
       <------>          <--------->           
1, 4, 8, 2, 5, 3, 7, 6, 10, 12, 11, 9, 13, 16, ...

Ve sonra 4 , 5 , 6 vb. İçin:

1, 4, 8, 2, 5, 3, 7, 6, 10, 12, 11, 9, 13, 16, ...
1, 4, 8, 6, 5, 3, 7, 2, 10, 12, 11, 14, 13, 16, ...
1, 4, 8, 6, 12, 3, 7, 2, 10, 5, 11, 14, 13, 16, ...
1, 4, 8, 6, 12, 14, 7, 2, 10, 5, 11, 3, 13, 16, ...
...

Sonra k tür adımlar, ilk k + 1 numaraları düzeltilecektir. Böylece, Shotgun sayılarının sonsuz sırasını, k'nın sonsuzluğa gitmesine izin verme sınırı olarak tanımlayabiliriz . İlk 66 sayı:

1, 4, 8, 6, 12, 14, 16, 9, 18, 20, 24, 26, 28, 22, 39, 15, 36, 35, 40, 38, 57, 34, 48, 49, 51, 44,
46, 33, 60, 77, 64, 32, 75, 56, 81, 68, 76, 58, 100, 55, 84, 111, 88, 62, 125, 70, 96, 91, 98, 95,
134, 72, 108, 82, 141, 80, 140, 92, 120, 156, 124, 94, 121, 52, 152, 145, ...

Eğlenceli gerçek: Sadece doğal sayılara izin verilerek elde edilmesine rağmen, bu dizi hiçbir asal içermez.

Meydan okuma

Bir tamsayı verildiğinde n > 0, nth Shotgun numarasını bulun . STDIN (veya en yakın alternatif), komut satırı argümanı veya işlev argümanı yoluyla giriş alarak bir program veya işlev yazabilir ve çıktısını geri döndürebilir veya STDOUT'a (veya en yakın alternatife) yazdırabilirsiniz.

Bu kod golf, yani en kısa gönderme (bayt cinsinden) kazanır.

Liderler

Bu düşündüğümden daha fazla cevap alıyor, aynı dilde rekabet eden birkaç insan. Yani burada hem düzenli bir lider tablosu hem de kazananların dile göre bir genel bakışını oluşturmak için bir Stack Snippet.

Cevabınızın göründüğünden emin olmak için, lütfen aşağıdaki Markdown şablonunu kullanarak cevabınızı bir başlık ile başlatın:

# Language Name, N bytes

Gönderinizin Nbüyüklüğü nerede ? Puanınızı artırmak varsa, olabilir onları içinden vurarak, başlığa eski hesapları tutmak. Örneğin:

# Ruby, <s>104</s> <s>101</s> 96 bytes


1
Bu eğlenceli gerçek çılgınca, bu algoritma tüm asal harfleri sonuna kadar karıştırıyor. Yoksa gerçekleşmeyecek başka doğal sayılar var mı?
Devon Parsons,

1
@DevonParsons Evet, tüm astarları "sonuna kadar" karıştırır. Ama bence eksik başka numaralar da var. Öyle görünüyor 10, 21, 25ve 30örneğin, ya görünmez.
Martin Ender

3
Bu bir Project Euler sorusu gibi geliyor. Öyle olduğunu sanmıyorum ... ama belki de öyle olmalı.
Corey Ogburn,

9
Genel olarak, kyinelemede, kdizideki th elemanı 2kth. pozisyonuna geçirilir ve incinasyona kadar tekrar dokunulmaz 2k, bu sırada 4kth. Asal bir sıra gelene kadar aktarılmaz, tabiri caizse, bütün asallar ileri karıştırılır. Ancak masum kurbanların listesini, yalnızca yinelemede 2 aktarılacak olan ilk elemanı ve her bir yinelemeyi yazdırarak kolayca yapabiliriz. Liste şu şekilde: 2, 3, 5, 7, 10, 11, 13, 21, 17, 19, 30, 23, 27, 25, 29, 31, 45, 42, 37, 54, 41, 43, 65, ...
Théophile

3
@ Sherlock9 Yapıldı! Onaylandığı takdirde, https://oeis.org/A266679 . Mutlu Yıllar!
Théophile

Yanıtlar:


5

Pyth, 19 22

u-G*H^_!%GH/GHrhQ2Q

@ PeterTaylor'un golf senaryosunun cevabının oldukça saf bir uygulaması .

Burada çevrimiçi deneyin

Bu, bir süre döngüsünü, aşağıdaki diğer Pyth programının yaptığı gibi bir katlamaya dönüştürmek için aynı hileleri kullanır.


u+G**H!%GHty%/GH2rhQ2Q

@ Sp3000'in algoritmasının saf bir kopyası Pyth'a çevrilmiş.

Burada çevrimiçi deneyebilirsiniz

While döngüsü öykünmek için azaltma (python'un adı). Üzerinde O sıralar range(input, 2)Pyth hangi dışarı çalışır range(2, input)[::-1]. Pyth ile ilgili diğer golf sahaları, sayısal argümanların değerini iki katına çıkarmak için gizli modunu kullanmak notyerine kullanmak <2ve kullanmaktan ibarettir y.


21

> <>, 52 45 bayt

> <> İçin ösolangs sayfası

i:&&:&1-?vn;
2*1-*+20.>:&:&%1(&:&*{:}&:1-&,2%

İhtiyaç duyulan çeşitli modülo ve çarpma işlemleri sayesinde etrafta birçok kopyalama ve taşıma elemanı vardır. Mantık Python çözümümle tamamen aynı .

Alır bir kod noktası aracılığıyla girdi örn STDIN'den gelen "!" = 33 -> 75.


10
Ve şimdiye kadarki en garip giriş formatı ödülünü
aldın

Yine de +1, endişelenme :)
Caridorc

@ Sp3000 IMO sadece bir olarak
sayılmalıdır

@ SuperJedi224 Aslında, bu meta yazıya göre, görünüşe göre -vüç olarak sayılıyor: /
Sp3000

17

Python 2, 58 bayt

i=n=input()
while~-i:n+=(n%i<1)*i*(n/i%2*2-1);i-=1
print n

Diğer cevapların çoğu gibi, fikir de geriye doğru çalışmaktır.


Şimdi adım k+1adım diyelim i, böylece adım adım ikatları ideğiştirilir. İki basit gözleme ihtiyacımız var:

  • Pozisyon ndizide sadece adımında takas edilir ieğer nbölünemeyen i,
  • Takasta daha düşük veya daha yüksek sayı olup olmadığını söylemek için, bakın n/i mod 2. Eğer bu 1 ise, en düşük sayı sizsinizdir (ve değişecektir), aksi takdirde en yüksek sayı sizsiniz demektir (ve aşağıya doğru kaybedersiniz).

Bu bize geriye doğru çalışmak için bir algoritma veriyor. Son adımdan başlayarak 6 ile deneyelim i = 6:

Step 6: Position 6 swaps with position 12 (6 is divisible by 6, 6/6 = 1 == 1 mod 2)

Şimdi sayının 12 konumundan geldiğini biliyoruz. Sonra:

Step 5: No swap (12 not divisible by 5)
Step 4: Position 12 swaps with position 16 (12 is divisible by 4, 12/4 = 3 == 1 mod 2)

Şimdi bunun 16'dan önce geldiğini biliyoruz. En sonunda:

Step 3: No swap (16 not divisible by 3)
Step 2: Position 16 swaps with position 14 (16 divisible by 2, 16/2 = 8 == 0 mod 2)

Bu ilk adım olduğu için (hatırlayın k+1) bittik ve 6. pozisyonda biten sayı başlangıçta 14 konumundan geliyor, yani 6. av tüfeği sayısı 14.

Şimdi Python açıklaması için:

i=n=input()             Read input, and store into i (step) and n (position)
while~-i:               while i-1 != 0:, or since we're descending with i this is just while i>1:
  n+=                   Add to the current position...
    (n%i<1)*            1* whatever's next if n is divisible by i, otherwise 0* (i.e. nothing)
    i*                  How many positions n might go up/down
    (n/i%2*2-1)         n/i%2 tell us higher/lower, *2-1 maps 0 or 1 to -1 (down) or +1 (up)
  i-=1                  Decrement the step number
print n                 Output

yazma için ilginç bir yol i-1olarak~-i
mbomb007

6
@ mbomb007: Kabul edildi. Zekice olsa da, aynı anlama geldiğinden ancak sonradan bir alana olan ihtiyacı ortadan kaldırıyor while. İyi işti, Sp3000.
Alex A.

Bunu kısa sürede alabileceğim en kısa sürede azaltma kullanarak oldu:u+G**H!%GHty%/GH2rhQ2Q
FryAmTheEggman 4:15

1
@FryAmTheEggman, Sp3000, hiçbiriniz bunu göndermeyecek misiniz?
Martin Ender

@ MartinBüttner Çok fazla bir kopyasını hissettiğimi düşündüğüm gibi göndermedim. Şimdilik CW cevabı olarak göndereceğim.
FryAmTheEggman 11:15

6

Haskell, 68 bayt

n#k|mod k(2*n)<1=k-n|mod k n<1=k+n|k>0=k
s n=foldr((.).(#))id[2..n]n

Muhtemelen daha da golf oynayabilir, özellikle de ilk sırada. Bu , th tüfeği numarasını salan nve döndüren bir işlevi tanımlar n.

map s [1..66]
[1,4,8,6,12,14,16,9,18,20,24,26,28,22,39,15,36,35,40,38,57,34,48,49,51,44,46,33,60,77,64,32,75,56,81,68,76,58,100,55,84,111,88,62,125,70,96,91,98,95,134,72,108,82,141,80,140,92,120,156,124,94,121,52,152,145]

açıklama

Yardımcı işlev #iki sayı alır nve her bir sayıya çift ​​değiştirme işlemi uygulanarak tanımlanan listede bu sayıyı kdöndürür . Örneğin, bunu ilk 20 sayıya uygulayarak şunu verir:knn = 4

map (4#) [1..20]
[1,2,3,8,5,6,7,4,9,10,11,16,13,14,15,12,17,18,19,24]

Bunun sonucu s n, listeyi bir sayı ve bir işlev (başlangıçta kimlik işlevi ) alan ve alan ve döndüren bir işlevi döndüren [2..n]ikinci dereceden işlev ile küçültmek ("katlamak") ile elde edilir . Örneğin , liste alan ve dönen bir işleve indirgenir . Yalnızca temel durum için gerekli olan listesi boş. Son olarak, bu fonksiyona thgungun sayısını elde ederek girdi verdik .(.).(#)mfidkf (m # k)n = 4[2,3,4]kid (4 # (3 # (2 # k)))idn = 1k = nn



5

Ruby, 92 bayt

def s(d,n)
d==1?n:s(d-1,n%d==0?n+(n%(d*2)==0?-d :d):n)
end
n=ARGV[0].to_i
print s(n,n).to_s

İlk kod golf çabam. Başka hiçbir cevaba göre değil.


Şimdi diğerlerinden bazılarına baktığımda, girdi kabul eden ve çıktı üreten tam bir program değil, sadece bir işlev tanımladığının farkındayım. OP, giriş ve çıkış ile komple bir program istedi. Bu tür gereksinimleri görmezden gelmek geleneksel mi?


84 Bayt

n=ARGV[0].to_i
d=n
while d>1
n+=(n%d==0?(n%(d*2)==0?-d :d):0)
d-=1
end
print n.to_s

Diğer cevaplara bakıp yinelemeli bir çözümün mümkün olduğunu fark ettikten sonra.


2
1. Değişim: En 84 bayt çözümü için birkaç iyileştirmeler ARGViçin $*sihirli küresel. 2. to_sGereksiz. Bunun yerine atama 3. diçin nayrı bir satıra, sadece yapmak d=n=...bir karakteri tıraş etmek. İlk golfünüz için iyi iş! :)
Doorknob

1
Tam bir programı nereden istiyorum? "Bir program veya işlev yazabilirsiniz ...";) (Bu, kod golfü zorlukları için de varsayılandır , ancak genellikle bütünlüğü sağlamak için de eklerim.)
Martin Ender

@ Doorknob'un önerilerini eklemek için, n+=hat üzerindeki iki parantez kümesi gerekli değildir ve her ikisi ==0de güvenli bir şekilde değiştirilebilir <1.
Peter Taylor

5

Python 2, 97 79 karakter

g=lambda n,k:n>1and g(n-1,k-(k%n<1)*n*(-1)**(k/n%2))or k
n=input()
print g(n,n)

Her indeks için doğru değeri tekrar tekrar takip ederek doğru değeri belirler. Algoritma bağımsız keşfedildi.

düzenleme: Şimdi nilk numara yerine sadece th sayısını yazdırır n. Elbette yinelemeli bir yaklaşım daha kısa olacaktır, ancak Sp3000'in kodunu kopyalamak istemiyorum.


Evet, sanırım herkes bu konuda birleşecek. Bulduğum g(i,i)... parçası özellikle rahatsız edici karşın, yine de
SP3000

2
Dil, ifade nedeniyle Python 2 olarak işaretlenmelidir print.
mbomb007

@ mbomb007 Düzeltildi.
Jakube

4

Haskell, 79 bayt

1#i=i
s#i|i`mod`(2*s)==0=(s-1)#(i-s)|i`mod`s==0=(s-1)#(i+s)|1<2=(s-1)#i
p n=n#n

Kullanım: p 66hangi çıktılar145

Açıklamak için çok fazla şey yok: İşlev #, tüfek sayısını iadım konumunda tekrarlı olarak hesaplar s. adımdaki p nsayıyı döndürür .nn


Benim cevabını göndermeden önce cevabını görmedim. Görünüşe göre oldukça farklı yaklaşımlarımız var.
Zgarb

4

k, 41 bayt

{{x+$[y!x;0;$[2!_x%y;y;-y]]}/[x;|2+!x-1]}

 / apply to an int
 {{x+$[y!x;0;$[2!_x%y;y;-y]]}/[x;|2+!x-1]} 42
111
 / apply to 1 through 66
 {{x+$[y!x;0;$[2!_x%y;y;-y]]}/[x;|2+!x-1]}'1+!66
1 4 8 6 12 14 16 9 18 20 24 26 28 22 39 15 36 35 40 38 57 34 48 49 51 44 46 33 60 77 64 32 75 56 81 68 76 58 100 55 84 111 88 62 125 70 96 91 98 95 134 72 108 82 141 80 140 92 120 156 124 94 121 52 152 145
  • {...} lambda, x ve y, örtük 1. ve 2. argümandır
  • $[b;t;f] üçlü operatör, sırasıyla b ve ardından t / f değerini değerlendirir.
  • b!a bir modulo b
  • _ zemin, bölmenin sonucunu bir int a çevirir
  • % bölünme
  • {...}/[x;y] prime {...}, x ile y listesi üzerine uygulanır, f [f [.. f [f [x; y0]; y1]; .. yn-1]; yn] 'ye eşdeğerdir
  • | ters
  • ! iota işlevi, 0 ile n-1 arası bir liste oluşturur

4

Common Lisp, 113 91

(yinelemeli: 91)

(defun s(n)(do((r n(1- r)))((= r 1)n)(if(= 0(mod n r))(incf n(* r(if(oddp(/ n r))1 -1))))))

(orijinal, özyineli: 113)

(defun s(n &optional(r n))(cond((= r 1)n)((= 0(mod n r))(s(+ n(* r(if(oddp(/ n r))1 -1)))(1- r)))(t(s n(1- r)))))

Örnek

Özyinelemeli versiyonu ile:

(trace s)
(s 10)

  0: (S 10)
    1: (S 20 9)
      2: (S 20 8)
        3: (S 20 7)
          4: (S 20 6)
            5: (S 20 5)
              6: (S 15 4)
                7: (S 15 3)
                  8: (S 18 2)
                    9: (S 20 1)
                    9: S returned 20
         ...
    1: S returned 20
  0: S returned 20

Testler

Yinelemeli sürüm için kontroller ve önlemler:

(let ((list '(1 4 8 6 12 14 16 9 18 20 24 26 28 22 39 15 36 35 40 38 57 34 48 49 51 44
              46 33 60 77 64 32 75 56 81 68 76 58 100 55 84 111 88 62 125 70 96 91 98 95
              134 72 108 82 141 80 140 92 120 156 124 94 121 52 152 145)))
  (time
   (loop for r in list
         for n from 1
         always (= r (s n)))))

 => T

Evaluation took:
  0.000 seconds of real time
  0.000000 seconds of total run time (0.000000 user, 0.000000 system)
  100.00% CPU
  807,160 processor cycles
  32,768 bytes consed

4

Mathematica, 53 49 bayt

(For[i=n=#,n>1,--n,If[n∣i,i+=Mod[i,2n]2-n]];i)&

Referans uygulamamı golf yapmaya karar verdim. 3 bayt için "böler", ve sayıları için Unicode sembolüdür. Aksi takdirde, bu herkesle aynı algoritmayı kullanır.

nTek bir parametre olarak alan ve nth Shotgun numarasını döndüren adlandırılmamış bir işlev tanımlar .


4

GolfScript, 27 karakter

~.,(~%{):i\.@%!~)1$i/?i*-}/

açıklama

Eğer f(i, n)pozisyonda değerdir nsonra i-1dönüşümler, elimizdeki

f(1, n) = n
f(i, n) = f(i - 1, n % i == 0 ? (((n / i - 1) ^ 1) + 1) * i : n)  for i > 1

burada ^bitsel xor; Girilen nveriyi hesaplamak istiyoruz f(n, n).

Özyinelemeli bir işlevden bir döngüye dönüşüm ilginçtir; ilginç olan, hangi şekilde olduğu

n % i == 0 ? (((n / i - 1) ^ 1) + 1) * i : n

yeniden yazılabilir. Daha açık bir yaklaşım olması gerektiğini söylemek

n + (n % i == 0 ? i : 0) * g(n / i)

bazıları için g. Açıkçası garasında değişir 1ve -1pozisyonları dönüşümlü yukarı ve aşağı takas olarak; o zamandan beri g(1) = 1( 1takas 2ettiğimiz için ),

n + (n % i == 0 ? i : 0) * -1**(1 + n / i)

üstelleştirmeyi **ifade eder. Son tasarruf, bu şekilde yeniden yazmaktan geliyor

n - i * (n % i == 0 ? -1 : 0)**(n / i)

teşrih

~             # Evaluate input to get n
.,(~%{        # For n-1 downto 1...
  ):i         #   Let i be that value + 1, so for i = n downto 2...
  \.@%!       #   Find n % i == 0 ? 1 : 0
  ~)          #   Negate
  1$i/?       #   Raise to the power of n/i
  i*-         #   Multiply by i and subtract
}/

En kısa GS ve CJam cevaplarına sahip olduğunuzu görünce neden en kısa Pyth cevabına da cevap vermiyorsunuz? u-G*H^_!%GH/GHrhQ2QBunu kendin göndermek istemiyorsan, bana CW cevabına söyle / ekle.
FryAmTheEggman 11:15

@FryAmTheEggman, CJam'da pek pratik olmayabilir, ancak en azından az çok okuyabilirim. Yorumunuzdaki Pyth'in ne söylediğine dair hiçbir fikrim yok, ancak bağlamda bu cevabın bir limanı olduğunu düşünüyorum. Bu yüzden göndermeniz en iyisidir, çünkü onunla ilgili soruları cevaplayabilirsiniz.
Peter Taylor


4

Julia, 61 57 bayt

n->(i=n;while~-i!=0 n+=(n%i<1)*i*(n÷i%2*2-1);i-=1;end;n)

Bu, tek bir argüman alan nve nth shotgun sayısını döndüren adsız bir işlev yaratır . Aramak için bir isim verin, örneğin f=n->(...).

Örnekler:

julia> for i = 1:10 println(f(i)) end
1
4
8
6
12
14
16
9
18
20

Şu anda bu @ Sp3000'in harika Python cevabına dayanmaktadır . Bunu en kısa zamanda tekrar ziyaret edeceğim çünkü bunu Julia'da yapmanın benim yaptığımdan daha kısa bir yolu olmalı. Her zaman olduğu gibi herhangi bir giriş açığız.



3

CJam, 28 27 bayt

Yani bu biraz utanç verici ... bunu göndermeden önce, kendim golf oynamayı denedim ve CJam'da 30 bayta ulaştım. Mevcut cevapların hiçbiri henüz bunu geçmedi. Bu arada ben de üç bayt daha tıraş etmeyi başardım. Orada olan bir yorumda daha kısa Pyth çözümü, ancak daha kısa bir şey bu yüzden burada bir cevap gönderildi. Belki de APL / J insanlarına, kendi cevabımı kabul etmeden önce biraz daha fazla (ya da aslında Pyth çözümünü gönderen) denemeleri için ilham veriyor. ;)

l~__(,f-{_I_+%_+I-_zI=*+}fI

Burada test et.

açıklama

l~                          "Read input N and eval.";
  __(,                      "Duplicate twice, create range [0 1 2 ... N-2].";
      f-                    "Subtract each from N, giving [N N-1 N-2 ... 2].";
        {               }fI "For each element, storing the element in I.";
         _I_+%_+I-          "Compute 2(N % 2I)-I - the shuffling offset";
                  _zI=      "Check that this offset is ±I.";
                      *+    "Multiply the offset by this boolean and update to N.";

3

J, 3432 bayt

   (]+[*(1-~2*2|%~)*0=|)/@(_1}2+i.)

   ((]+[*(1-~2*2|%~)*0=|)/@(_1}2+i.)) every 1+i.20  NB. running with inputs 1..20
1 4 8 6 12 14 16 9 18 20 24 26 28 22 39 15 36 35 40 38

Biraz daha golf oynamaya çalışacağım ve daha sonra bir açıklama ekleyeceğim.

Burada çevrimiçi deneyin.



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.