Taban -1 + i cinsinden toplama


64

Gauss tamsayıları , tam sayıların a+biolduğu ave bher ikisinin de olduğu formun karmaşık sayılarıdır. Baz -1 + i, tüm Gauss tamsayı benzersiz basamak kullanılarak temsil edilebilir 0ve 1işaret göstermek için bir simge için gerek olmadan.

Örneğin, 1100-1 + i tabanında, ondan bu yana 2 olan ondalık sayıyı gösterir.

1*(-1+i)^3 + 1*(-1+i)^2 + 0*(-1+i)^1 + 0*(-1+i)^0
= (2+2i) + (-2i) + 0 + 0
= 2

Giriş, basamak kullanarak gösterilen -1 + i tabanındaki iki Gauss tamsayısı olacaktır 01. Bu, aşağıdaki formlardan birini alabilir:

  • İki ayrı rakam dizesi,
  • 01Temel -1 + i sayılarını temsil eden iki ondalık sayı (örneğin 1100, temel -1 + i'deki 2 için),
  • Temel -1 + i sayılarını temsil eden iki ikili tam sayı (örneğin, ondalık 12veya 0b1100temel -1 + i'deki 2 için)
  • İki basamaklı dizgileri / ikili tam sayılarını tek bir alfasayısal olmayan ayırıcı ile ayıran tek bir dize (örneğin 1100 1100veya 12,122 + 2 için)

Ayrıca Gaussian tamsayıların toplamını, -1 + i üssünde ve rakamları kullanarak gösterir 01(aynı seçimde olmak zorunda değil, girdi olarak izin verilen formatlardan birinde). Çıktının sınırlı sayıda öncü sıfır içermesine izin verilir.

Her biri en fazla 30 basamaklı girişler için işleviniz veya programınız 2 saniye içinde sonlandırılmalıdır.

Ek açıklamalar

  • Girişin hiçbir yabancı satır sıfırı içermediğini varsayabilirsiniz. Özel 0 durumu 0için gösterimi olarak ya da boş dizgiyi seçebilirsiniz .

Test durumları

0, 0 => 0                                      # 0 + 0 = 0
0, 1 => 1                                      # 0 + 1 = 1
1, 1 => 1100                                   # 1 + 1 = 2
1100, 1100 => 111010000                        # 2 + 2 = 4
1101, 1101 => 111011100                        # 3 + 3 = 6
110111001100, 1110011011100 => 0               # 42 + (-42) = 0
11, 111 => 0                                   # i + (-i) = 0
11, 110 => 11101                               # i + (-1-i) = -1
10101, 11011 => 10010                          # (-3-2i) + (-2+3i) = (-5+i)
1010100101, 111101 => 1110100000100            # (-19+2i) + (3-4i) = (-16-2i)

Daha uzun test vakaları:

11011011010110101110010001001, 111100010100101001001010010101 => 0
111111111111111111111111111111, 111111111111111111111111111111 => 100100100100100100100100100100
101101110111011101110111011101, 101101110111011101110111011101 => 11101001010001000100010001000100011100
100100010101001101010110101010, 100010011101001011111110101000 => 110000110010101100001100111100010

Rakam listesi yok mu?
Hesap MakinesiFeline

@CatsAreFluffy Rakam listesi yok, üzgünüm.
Sp3000

96
Sen değiştirerek bir bayt kaydedebilirsiniz -1+iiçin i-1başlığında.
mbomb007 23.03

1
Şimdi tam tersi bir dönüşüme ihtiyacımız var. : P
Rɪᴋᴇʀ

3
Dünyada 1100 çeşit insan var. İkiliyi anlayanlar, yapmayanlar, üçlüyle karıştıranlar, üs 4 ile karıştıranlar, üs 5 ile karıştıranlar, üs -1 + i ile karıştıranlar, karıştıranlar üs 6, üs 7 ile karışanlar, üs 8 ile karışanlar, üs 9 ile
karışanlar

Yanıtlar:


42

Python 2, 98 97 91 84 bayt

s=input();L=1
for _ in`s`*8:s+=1098*int(str(s).translate('0011'*64));L*=10
print s%L

Bu ondalık sayıdaki G / Ç yapar. Tamsayılar alfanümerik olmayan karakterlerle ayrılmalıdır +.

2 baytlık golf oynamak için @xnor'a teşekkürler!

Üzerinde Deneyin Ideone .

Nasıl çalışır

Gelen Karmaşık Üs Aritmetik , yazar formu tabanlarında karmaşık sayılar ekleyip çoğalmaya nasıl gösterir -n + i .

Baz -1 + i için , iki farkla birlikte normal, binary eklemeye benzer şekilde ekleme yapılır:

  • Bunun yerine taşıma 1 sonraki daha yüksek bir konuma, biz taşımak 110 sonraki üç.

  • Taşıma basamakları süresiz olarak yayılabilir. Bununla birlikte, baştaki sıfırlar olmadan, a + b toplamı en fazla a ve b'den daha fazla sekiz basamağa sahiptir .

Aşağıdaki şekilde devam ediyoruz.

  1. Öncelikle, a ve b'yi basamakları ondalık basamakmış gibi ekleriz .

    For a = 10101 ve b = 11011 , bu verir 21112 .

  2. Daha sonra, daha basamak daha değiştirerek yeni bir numara oluşturur 1 bir ile 1 a, diğerleri 0 . 1

    Toplam 21112 için bu 10001 verir .

  3. 1'den büyük her bir rakam için , bu rakamdan 2 çıkarmalı ve 110'u bir sonraki üç yüksek konuma getirmeliyiz. 1098 = 10 * 110 - 2'den beri , bunu 2. adımdaki sonucu 1098 ile çarpıp , ardından bu ürünü toplamaya ekleyerek başarabiliriz . 2

    Toplam 21112 için , bu 21112 + 1098 x 10001 = 21112 + 10981098 = 11002210'u verir .

  4. Adım 2 ve 3'ü toplam d * 8 kez tekrar ediyoruz , burada d a + b'nin hane sayısıdır . 3

    İlk toplam 21112 için sonuçlar

                          11002210
                          12210010
                        1220010010
                      122000010010
                    12200000010010
                  1220000000010010
                122000000000010010
              12200000000000010010
            1220000000000000010010
          122000000000000000010010
        12200000000000000000010010
      1220000000000000000000010010
    122000000000000000000000010010
                                 .
                                 .
                                 .
    
  5. Son d + 8 rakamları hariç tümü hariç kalan son modülü 10 d + 8 alıyoruz .

    İlk toplam 21112 için nihai sonuç 10010'dur .


1 Bu çeviri ile elde edilir . Dize 0011 64 kez tekrarlamak, bir tekrarlamayı ASCII karakterleri 0123 dizisi ile hizalayarak istenen değişimi sağlar.

2 Bu toplamın rakamlarının 3 değerini geçemeyeceğini unutmayın (ilk değer 1 artı, iki 1 'nin taşıdığı değer).

3 Bu, d = 1 ve d * 8> d + 8 için işe yarar. Kod adımlarını tekrar edebilir X 8 (d + 1) için, kat s bir arka sahip L ise s a, uzun bir tam sayı.


7
Bu derin sihir . Hangi format input()bekliyor? (I get 21112zaman giriş 10101, 11011.)
Tim Pederick

1
Boşver; Python 3'e çevrilmiş (başarısız gibi görünüyor) bir sürüm çalıştırıyordu . Python 2 altında düzgün çalışıyor .
Tim Pederick

9
...Nasıl. Lütfen. Açıklamak.
Nic Hartley

@QPaysTaxes Cevabımı düzenledim.
Dennis,

@Dennis Şimdi bunun neden işe yaradığını açıklayabilir misiniz? Mesela neden d+8olmasın d+9? Nasıl????
Nic Hartley

16

Pyth, 34 bayt

_shM.u,%J/eMeN\12-+PMeNm.B6/J2k,kQ

Çevrimiçi deneyin: Gösteri veya Test Paketi (biraz zaman alır). Çevrimiçi derleyici normal (çevrimdışı) derleyiciye kıyasla oldukça yavaş olduğundan, zaman kısıtlamasını kolayca karşılamalıdır.

Açıklama:

Algoritmam temel olarak taşıma işlemine ek bir uygulama. Ama bunun yerine taşıma ait 1, ben taşımak zorunda 110( 1100tabanında -1+iaynıdır 2tabanında -1+i). Bu daha çok işe yarar, ancak sonsuz döngü yazdırma sıfırlarına sıkışıp kalabilirsiniz. Örneğin siz ekliyorsanız 1ile 11ve halen carry var 110. Bu yüzden temelde bir döngüde sıkışıp kalıncaya kadar eklerim ve sonra dururum. Ben bir döngü her zaman sıfır yazdırır bir döngü olduğunu ve bu nedenle bu iyi olması gerektiğini düşünüyorum.

_shM.u,%J/eMeN\12-+PMeNm.B6/J2k,kQ   implicit: Q = input list of strings
                               ,kQ   create the pair ["", Q]
    .u                               modify the pair N (^) until loop:
      ,                                replace N with a new pair containing:
            eN                           N[1] (the remaining summand)
          eM                             take the last digits of each summand
         /    \1                         count the ones
        J                                store the count in J
       %J       2                        J % 2 (this is the first element of the new pair)
                   PMeN                  remove the last digit of each summand
                  +    m   /J2           and add J / 2 new summand:
                        .B6                 with the value "110" (binary of 6)
                 -            k          remove empty summand
    .u                               returns all intermediate results
  hM                                 extract the digits
 s                                   sum them up to a long string
_                                    reverse

13

Python 2, 69 67 bayt

f=lambda a,b:a*a+b*b^58and 2*f(a*b%2*6,f(a/2,b/2))|a+b&1if a else b

G / Ç, temel 2 tamsayılarıyla yapılır.

-2 teşekkürler @Dennis.


Ne a*a+b*b^58==0zaman alıyorum ave bters mi? Bu nasıl çalışıyor?
xnor

@xnor Hayır, a*a+b*b==58biri 3, diğeri 7 olduğunda
feersum

1
Bunun (3,7)bir döngü veren ve özel kasaya ihtiyaç duyan tek çift olduğu benim için belli değil . Eğer doğruysa, o zaman aslında (a,b)==(3,7)bu sırayı kontrol (7,3)etmeniz yeterlidir , çünkü işe geri döner (3,7)ve bunun için daha kısa bir ifade vardır.
xnor

1
Şimdi bu (a) (ya da unutur) bilmeyen kimseyi şaşırtmak için garanti edilir ^, XOR olduğunu üs alma değil, veya (b) XOR daha düşük önceliğe sahiptir +.
Tim Pederick

12

Retina , 100 bayt

r+`(.*)(\d|(?!\4))( .*)(.?)
$2$4:$1$3
T` 0
+`1:11(1*:1*)11
:$1
^:*
:::
}`:(1*:1*:)11
1:1$1
(1)*:
$#1

Bu, girişi virgülle ayırarak alır. Çıkış her zaman üç önde gelen sıfır ile başlar.

Çevrimiçi deneyin!

İlk aşamada daha kısa bir çözüm olup olmadığını merak ediyorum ...


2
Hayır, hayır, skor olduğu gibi mükemmel;)
Conor O'Brien

2
Güzel skor -2i!
Nic Hartley

Vay. Benimkini gönderdiğimde bu çözümü görmedim ... Benim çözümümden çok daha üstün.
Sızdıran Rahibe

@KennyLau Sadece bakıyordum ve "hm, sanırım bir noktaya bir açıklama eklemeliydim ..." diye düşündüm.
Martin Ender

...- 2i? Bu ondalık ama program olmayan bir temel kullanıyor.
user75200,

12

Jelly, 29 28 26 24 21 20 bayt

DBḅ1100ḌµDL+8µ¡Dṣ2ṪḌ

Bu ondalık sayıdaki G / Ç yapar. Tamsayılar alfanümerik olmayan karakterlerle ayrılmalıdır +.

Çevrimiçi deneyin! veya tüm test durumlarını doğrulayın .

Arka fon

Gelen Karmaşık Üs Aritmetik , yazar formu tabanlarında karmaşık sayılar ekleyip çoğalmaya nasıl gösterir -n + i .

Baz -1 + i için , iki farkla birlikte normal, binary eklemeye benzer şekilde ekleme yapılır:

  • Bunun yerine taşıma 1 sonraki daha yüksek bir konuma, biz taşımak 110 sonraki üç.

  • Taşıma basamakları süresiz olarak yayılabilir. Bununla birlikte, baştaki sıfırlar olmadan, a + b toplamı en fazla a ve b'den daha fazla sekiz basamağa sahiptir .

Aşağıdaki şekilde devam ediyoruz.

  1. Öncelikle, a ve b'yi basamakları ondalık basamakmış gibi ekleriz .

    For a = 10101 ve b = 11011 , bu verir 21112 .

  2. 1'den büyük her bir rakam için , bu rakamdan 2 çıkarmalı ve 110'u bir sonraki üç yüksek konuma getirmeliyiz. Bunu her ondalık basamağı ikiliye, sonuçta ortaya çıkan ikili dizileri 1100 tabanından tam sayıya dönüştürerek elde edebiliriz ve elde edilen 0 ', 1 , 1100 ve 1101 ' lerin kanonik olmayan bir taban 10 olarak yorumunu yapabiliriz. numara. 1

    Toplam 21112 için , bu 21112 + 1098 x 10001 = 21112 + 10981098 = 11002210'u verir .

  3. 2 numaralı adımı toplam d + 8 kez tekrarlıyoruz , burada d a + b'nin hane sayısıdır .

    İlk toplam 21112 için sonuçlar

                          11002210
                          12210010
                        1220010010
                      122000010010
                    12200000010010
                  1220000000010010
                122000000000010010
              12200000000000010010
            1220000000000000010010
          122000000000000000010010
        12200000000000000000010010
      1220000000000000000000010010
    122000000000000000000000010010
    
  4. Nihai sonuçtan son d + 8 basamağı dışındakileri atıyoruz. Bu, son 2’den sonraki herşeyi atmak suretiyle elde edilir . 2

    İlk toplam 21112 için nihai sonuç 10010'dur .

Nasıl çalışır

DBḅ1100ḌµDL+8µ¡Dṣ2ṪḌ  Main link. Argument: a + b (implicit sum)

        µ    µ¡       Execute the chain before the first µ n times, where n is
                      the result of executing the chain before the second µ.
         D            Convert a + b to base 10.
          L           Length; count the decimal digits.
           +8         Add 8 to the number of digits.
D                     Convert the initial/previous sum to base 10.
 B                    Convert each digit (0 - 3) to binary.
  ḅ1100               Convert each binary array from base 1100 to integer.
       Ḍ              Interpret the resulting list as a base 10 number.
               D      Convert the final sum to base 10.
                ṣ2    Split at occurrences of 2.
                  Ṫ   Select the last chunk.
                   Ḍ  Convert from base 10 to integer.

1 Bu toplamın rakamlarının 3 değerini geçemeyeceğini unutmayın (ilk değer 1 artı, iki 1 'nin taşıdığı değer).

2 Bu işe yarıyor çünkü iptal edilecek son rakam 3 olamaz .


6

Python 3, 289 bayt

Bu, en az en önemli haneye (başka bir deyişle, ilkokulda öğretildiğiniz aynı algoritmayı) sayısal olarak toplama işlemini gerçekleştirir. Farklılıklar şudur: (a) ikiliktir, ondalık değildir, yani bir basamak 2 ya da daha fazla olduğunda taşırsınız ve (b) 1 + 1 = 1100yapmazsınız 10.

Aslında, aynı zamanda 11 + 111 = 0, sıfır olması gereken toplamların veya asla sona ermeyeceğini not etmek gerekir.

from collections import*
def a(*s,p=0):
 r=defaultdict(int,{0:0})
 for S in s:
  n=0
  for d in S[::-1]:r[n]+=d=='1';n+=1
 while p<=max(r):
  while r[p]>1:
   r[p]-=2
   if r[p+1]>1<=r[p+2]:r[p+1]-=2;r[p+2]-=1
   else:r[p+2]+=1;r[p+3]+=1
  p+=1
 return str([*map(r.get,sorted(r))])[-2::-3]

Elbette daha fazla golf oynamak mümkündür.


Sıfır dedektörünüzün yeterli olduğuna ne kadar eminsiniz?
Yakk

4
@Yakk: Hakemli dergilerden birinin ölçeğinde, belki de henüz bir karşı örnek yok mu?
Tim Pederick

2

Retina, 157 151 134 133 124 123 bayt

Martin Büttner sayesinde 1 bayt kapalı.

(.+),(.+)
$.1$*0$2,$.2$*0$1,
1
0x
+`(0x*)(,.*)0(x*),
$2,$1$3
{`,

(^|0x0xx0xx)
000
(0x*)(0x*)(0x*0)xx
$1x$2x$3
)`^0+
0
0x
1

Çevrimiçi deneyin!

Birliğe dönüştürür ve ardından aşağıdaki değiştirmeleri tekrarlayın (burada ondalık olarak gösterilmiştir):

122 -> 000
0002 -> 1100 (this can also be 0012 -> 1110 and 1112 -> 2210 or even 2222 -> 3320 or even 3333 -> 4431)

Temel olarak, ikiden büyük olduğunda: ikisini al, önceki haneye hiçbir şey ekle, bir önceki haneye bir tane ekle, sonra bir önceki haneye bir tane ekle.

Sözde kodda:

if(a[n]>2):
    a[n] -= 2;
    a[n-2] += 1;
    a[n-3] += 1;

Unary uygulama:

Her hane (örn. 3) xS (eg xxx) sayısı olarak gösterilmiş ve sonra eklenmiş olarak 0.

Örneğin, 1234olarak ifade edilir 0x0xx0xxx0xxxx.

Bu 0, 101ifade edildiği gibi değişmeden kalır 0x00x.

Başlangıçta ve sonunda bu yana, sadece orada olduğu 0ve 1dönüşüm kolaylıkla yapılabilirdi 1->0xve 0x->1.

Her adımı görmek için buraya tıklayın .


1

JavaScript (ES6), 146 126 bayt

r=n=>n&&n%2-r(n>>=1)-i(n)
i=n=>n&&r(n>>=1)-i(n)
g=(x,y,b=(x^y)&1)=>x|y&&b+2*g(b-x+y>>1,b-x-y>>1)
(x,y)=>g(r(x)+r(y),i(x)+i(y))

gtabanına bir Gauss tamsayı (gerçek ve sanal parça) dönüştürür i-1, süre rve ibir baz dönüştürür i-1(sırasıyla gerçek ve sanal parça) bir Gauss tamsayı tamsayı. Dönüşümler gerçekleştiğinde, sadece aritmetik işlem yapmam gerekiyor.

Düzenleme: Gerçek ve hayali parçaları ayrı ayrı hesaplayarak 20 bayt kurtardı.


1

C ++ 416 bayt, artı #include <vector>\n#include <algorithm>\n (başka bir 40)

using I=int;using v=std::vector<I>;void r(v&x){v r{rbegin(x),rend(x)};x=r;}v a(v L,v R){r(L);r(R);L.resize(std::max(L.size(),R.size()));for(int&r:R)L[&r-R.data()]+=r;while(1){L.resize(L.size()+3);auto it=find(rbegin(L),rend(L),2);if(it==rend(L))break;I i=-1+it.base()-begin(L);i&&L[i+1]&&L[i-1]/2?L[i+1]=L[i]=L[i-1]=0:(++L[i+2],++L[i+3],L[i]=0);}L.erase( std::find(rbegin(L),rend(L),1).base(),end(L));r(L);return L;}

veya daha fazla boşlukla:

using I=int;
using v=std::vector<I>;

void r(v&x){v r{rbegin(x),rend(x)};x=r;}
v a(v L,v R) {
  r(L);r(R);
  L.resize(std::max(L.size(),R.size()));
  for(int&r:R)
    L[&r-R.data()]+=r;
  while(1) {
    L.resize(L.size()+3);
    auto it=find(rbegin(L), rend(L), 2);
    if(it==rend(L)) break;
    I i=-1+it.base()-begin(L);
    i&&L[i+1]&&L[i-1]/2?
      L[i+1]=L[i]=L[i-1]=0
    :
      (++L[i+2],++L[i+3],L[i]=0);
  }
  L.erase( std::find(rbegin(L),rend(L),1).base(), end(L));
  r(L);
  return L;
}

Ancak golf oynadı. Girdiyi bir ints vektörü olarak alır ve ints in bir vektörünü döndürür.

Canlı bir örnek .

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.