Dallanma lütfen


14

Orta düzeyde düşük seviyeli kod optimizasyonuna sahip olan herkes, if-ifadeleri, döngüler veya select-ifadeleri olarak uygulandığında, şube yanlış tahmin olasılığı korkunç bir saat kaybıdır.

Basit problemler basit aritmetik ile çok daha iyi çözülebilir, hadi bunu yapalım.

Aşağıdaki sorunlar için tüm değişkenler 32 bit işaretsiz tamsayılardır ve izin verilen tek kod, yalnızca aşağıdaki işleçleri içeren düz ayarlı deyimlerdir:

+ addition
- subtraction
* multiplication
/ integer division, rounds down, division by 0 not allowed
% modulo
& binary and
| binary or
^ binary exclusive or
>> bitshift right
<< bitshift left

Logic operators, return 1 if the expression is true and 0 if it is false.
== equal
!= not equal
< less than
<= less than or equal
> greater than
>= greater than or equal

Set operator
=

Her satır, değişken bir tanımlayıcı ve onu izleyen bir işleç ve ardından bir ifade içermelidir.

Bir ifade ek küme işleçleri içeremez, ancak değişken tanımlayıcıları, değişmez sayılar ve parantezler içerebilir.

Golf skoru sadece operatör sayısını sayar.

Misal:

myvar = ( ( ( foo + 5 ) * bar ) % 7 ) == 3

5 operatör puanı var.

Bir çözüm, yazarın uygun gördüğü kadar çok değişken içerebilir.
Ayarlanmamış değişkenlerin değeri vardır 0.
Taşma ve taşmaya izin verilir, tüm negatif sayılar taşar, bu 3 - 5da 4294967294daha büyük bir ifadenin parçası olarak bile.

Görev 1: Maks.

İki değer Ave Bkapsamda var olan RESULTdeğişken, program sona erdiğinde bu değerlerin en büyüğünü içermesini sağlar.

Görev 2: Medyan

Üç değerleri A, Bve C, kapsam var olmaları RESULTdeğişken bu değerler zaman programı sonlandırıldığında ortancasını içerirler.

Görev 3: Karekök

AKapsamda var olan bir değer, RESULTdeğişkenin Aprogram sona erdiğinde yuvarlatılmış kare kökünü içermesini sağlar .

Soruların yalnızca bir veya ikisine bir cevap göndermeniz uygundur, bazılarınıza sadece geçerli çözümler bulmak zor olacaktır.


Tekli operatörler nerede? Umurumda değil -ama ~güzel olabilir (ne için olduğunu bilmesem bile).
John Dvorak

Tabii 0xFFFF_FFFF_FFFF_FFFF ^ xve 0 - x. Nasıl unutmuş olabilirim?
John Dvorak

@JanDvorak O değil tamlık mantık için, en kısa açıklamayı yaptı !da hayli abes: x == 0.
aaaaaaaaaaaa

Sıfıra bölme davranışı nedir?
John Dvorak

Mathematica'da (a> b) True veya False değerini döndürür. Boole False değerini 0 ve True değerini 1'e dönüştürür. Kullanımı yasal mı Boole[a-b]?
DavidC

Yanıtlar:


5

Görev 3, 23 ops

x = (A >> 16) + A / ((A >> 13) + 511) + 15
x = (x + A/x) >> 1
x = (x + A/x) >> 1
x = (x + A/x) >> 1
RESULT = x - (x > A/x)

Diğer çözümlerin yaptığı gibi Newton yöntemini kullanarak daha dokunaklı bir tohumla. İlk bit A >> 16aralığın üstünü mutlu A / ((A >> 13) + 511)tutar , ikinci bit aralığın ortasını mutlu ve son bit 15altını tutar ve ayrıca sıfır hatalarla bölünmeyi önler (15, 0doğru bir şekilde birleşmeyi sağlayan mümkün olan en büyük değerdir - yarıya üç kez eksi düzeltme sıfıra eşittir). Giriş değerleri 225, 275625, 82137969, 2908768489(ve yakındaki değerler) için ilk tohum kesindir. Aralıktaki tüm kenar kasaları (mükemmel kareler, mükemmel kareler + 1 ve mükemmel kareler - 1) 0 .. 2**32-1test edilmiştir ve doğrudur.

Kurallar hakkında birkaç yorum:
Taşma ve taşmaya izin verilir, tüm negatif sayılar taşar, bu nedenle 3 - 5, daha büyük bir ifadenin parçası olarak bile 4294967294'tür .

Bu son parça bir inovasyon katili gibi görünüyor. Başlangıçta Halley yönteminin genelleştirilmiş bir formunu kullanarak bir çözüm denedim , ancak yukarıdaki kısıtlama göz önüne alındığında bunun geçersiz olduğunu fark ettim. Yineleme (kare köklere uygulandığı gibi) şudur:

x = x * (3*A + x*x) / (A + 3*x*x)

Bu yineleme Newton'un yapmadığı güzel niteliklere sahiptir. Kübik olarak (kuadratik olarak) birleşir, yukarıdan veya aşağıdan (sadece yukarıdan ziyade) birleşir ve kötü seçilmiş bir tohuma o kadar duyarlı değildir (Newton'un yinelemesine çok düşük bir tohum verilirse, yakınsama noktasını büyük ölçüde vuruyor ve sonra geri gitmesi gerekiyor).

Newton'un yönteminde de (en azından tamsayılarla uğraşırken), A / x - x = 2 gibi bir x değerine ulaşması sorunu vardır, bu durumda, uygun tamsayı kökünden daha büyük bir değere yakınsar, düzeltilmesi gereken; Halley yönteminin böyle bir düzeltmeye ihtiyacı yoktur. Ancak ne yazık ki, değeri genellikle izin verilen 32 bit tam sayı alanından daha büyük olacaktır.3*A + x*x

Orada diğer jeneralize n bir dizi inci kök algoritmaları, ama hepsi pay aynı karakteristik:

x = x + x*(v - x**n)/(v*n)
x = (x*(n+1) - x**(n+1)/v)/n
x = ((n-2)*x + (4*v*x)/(v + x**n))/n
x = x*((n+2)*v + (n-2)*x**n)/(v + x**n)/n
x = ((n-2)*x + (n*x*v)/(v + (n-1)*x**n))/(n-1)
x = ((n-2)*x + x*((n*2-1)*v + x**n)/(v + (n*2-1)*x**n))/(n-1)

x = x + 2*x*(v - x**n)/(v + x**n)/n
x = x + x*31*(v - x**n)/(10*v + 21*x**n)/n
x = x + x*561*(v - x**n)/(181*v + 380*x**n)/n
x = x + x*1153*(v - x**n)/(372*v + 781*x**n)/n

Bunların çoğu ya kübik ya da kuadratik yakınsama gösterir. Son dördü, dörtlü yakınsama üzerinde yakınsama yapan bir dizi iterasyonun parçasıdır. Ancak praxis'te, yüzlerce haneyi hesaplamanız gerekmedikçe, Newton'un yöntemi daha az işlemle ihtiyacınız olanı alır.


Çok güzel, ama 4294967295 için başarısız. Kurallara gelince, ilginç hale getirmek için sıkı olmalılar. Hangi tesislerin en iyi meydan okumayı yaptığını tartışabilirsiniz, ancak sonuçta kuralların tam olarak izin verdiklerinden daha net ve açık olması çok daha önemlidir.
aaaaaaaaaaaa

Ben Halley zaten buna değer olacağını sanmıyorum, uzak bir tahmin 3 kat biraz daha az artacaktır, Newton 2 kat biraz daha az yapar. Benzer şekilde iyi bir tahmin Halley üçlü olacak doğruluk, Newton iki katına çıkar. Yani bir Halley yinelemesi tam olarak log(3)/log(2) ~= 1.585Newton yinelemelerine değer .
aaaaaaaaaaaa

@ eBusiness Başlangıçta 2 Halley benzer seçilmiş bir tohum toplam 25 ops vardı - ne zaman hata ile A = 0- yani bu aslında daha kısa. Yaklaşık 4294967295 , bu bir gözetimdi: 65536² ≡ 0 olarak , düzeltme yinelemesi düzeltilemez. Alternatif bulup bulamayacağımı göreceğim.
primo

@eBusiness düzeltildi.
primo

Paketin en şık karekökü, iyi iş ve resmi bir zafer rozeti.
aaaaaaaaaaaa

5

65 (61) işlem (5 + 13 + 47 (43))

Görev 1 - Maks (A, B)

RESULT = A + (B - A) * (A <= B)

Bu bariz bir çözümdür. Ödeve ihtiyacınız var, karşılaştırmaya ihtiyacınız var, karşılaştırmayı bir şeyle çarpmanız gerekiyor, çarpı değişkenlerden biri olamaz ve ürün sonuç olamaz.

Görev 2 - Orta (A, B, C)

RESULT = A                               \
       + (B - A) * (A > B) ^ (B <= C)    \
       + (C - A) * (A > C) ^ (C <  B)

Bu, üç değişkenin tümünü koşullandıran önceki 15-op'luk çözümümün üzerinde bir gelişmedir - bu iki çıkarma çıkardı, ancak başka bir merkeziyet testi yaptı. Testin kendisi basittir: bir eleman ortada, ikisinden tam olarak diğeri yukarıdadır.

Görev 3 - sqrt (A)

X1     = 1024 + A / 2048
X2     = (X1  + A / X1 ) / 2
...
X10    = (X9 + A / X9 ) / 2
RESULT = X16 - (X16 * X16 > A)

Onbir newton yaklaşımı turu. 1024 sihirli sabiti zaten WolframW tarafından dövüldü (ve 512 = 2 ** 32 yakınsamadan önce a = 0 için sıfıra bölünmeye neden oluyor), ancak 0/ 0'u sıfır olarak tanımlayabilirsek, on yineleme başlangıç ​​değeri ile çalışacaktır On yinelemeyle ilgili iddiamın tamamen temiz olmadığını itiraf ediyorum, ancak hala parantez içinde talep ediyorum. Ancak dokuzun mümkün olup olmadığını araştırmam gerekecek.WolframH çözümü olan dokuz yineleme.


Görev 3'ün ilk satırının doğru olmadığını düşünüyorum: ikinci sabit ilk sabitin 4 katı olmalıdır ("saf" Newton'a sahip olmak).
Monica'yı

@WolframH Daha iyi bir ilk tahmin, neden döngüleri harcadığımı açıklayabilir. 4 * ile nereden geldiniz? Bu, iki iterasyonun bir araya getirilmiş gibi görünüyor.
John Dvorak

(1024 + A/1024)/2 == (512 + A/2048)(bu X0 = 1024, ve sonra Newton'u başlatır).
Monica'yı

Görev 1 için güzel bir çözüm Columbus'un yumurtası.
DavidC


5

1: 5 operatörleri

RESULT = B ^ (A ^ B)*(A > B)

2: 13 operatör

RESULT = B ^ (A ^ B)*(A > B) ^ (A ^ C)*(A > C) ^ (B ^ C)*(B > C)

3: 27 operatör

g = 47|((0x00ffffff & A)>>10)|(A>>14)
r = (g + A/g)/3
r = (r + A/r)>>1
r = (r + A/r)>>1
r = (r + A/r)>>1
RESULT = r - (r*r-1>=A)

5

Görev 3, 39 İşlemler

EDIT: Son satır değişti; Yorumlara bakınız.

Bu Newthon yönteminin bir uygulamasıdır. Tüm pozitif karelerle ve ayrıca eksi bir pozitif karelerle ve ayrıca 0 ila 2 ^ 32-1 aralığında bir milyon rasgele sayı ile test edilmiştir. Görünüşte komik başlangıç değeri için kısa (1022 + A/1022) / 2yineleme az sayıda (Sanırım) ihtiyacı olan ve aynı zamanda yapar RESULTiçin A=0(için geçerli olmaz hangi hakkının 1024yerine 1022).

r = (511 + A/2044)
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
RESULT = r - (r > A/r)

Newton'un yönteminin sizinkiyle paralel olarak optimize edilmiş ve daha sonra iyi bir süre yayınlanmış olan alt kopyamı tutmalı mıyım? Büyük akıllar benzer düşünür ve çözümün iki iki yanıta bölünmesi kötüdür, ancak şu anki durum budur.
John Dvorak

@ JanDvorak: Sorduğunuz için teşekkürler. Cevabınıza biraz daha kısa bir yöntem koyarsanız sorun değil. Ayrıca, bana kredi verdiğiniz için teşekkürler :-)
Monica

Gerçekten güzel bir deneme, ancak 4294965360 - 4294967295 girişi için başarısız.
aaaaaaaaaaaa

@ eBusiness: Bu girdiler için hangi sonucu elde ediyorsunuz? Testlerimde 65535 olsun, sorun değil.
Monica

65536'yı alıyorum. Belki de öngörülen tam sayı biçimini kullanmıyorsunuzdur.
aaaaaaaaaaaa
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.