Yoğun bir şekilde paketlenmiş ondalık sayı (DPD)


26

Nandgame hayranları için: Lütfen DPD'yi mantık kapılarında ondalık saymaya çalışın !

Arka fon

Yoğun paketlenmiş ondalık (DPD) , ondalık basamakları ikili biçimde etkin biçimde saklamanın bir yoludur. 10 bitte üç ondalık basamağı (000 ila 999) depolar; bu, saf BCD'den (4 bitte bir basamak depolayan) çok daha verimlidir.

Gösterimler

  • Küçük harfler aiçin iondalık gösterimi kopyalanır parçalarıdır.
  • 0ve 1giriş veya çıkış bit desenlerindeki kesin bitlerdir.
  • x bitler dönüşümde göz ardı edilir.

Dönüşüm tablosu

Aşağıdaki 10 DPD bitinden üç ondalık basamağa kadar dönüşüm tablosudur. Her ondalık basamak 4 bit ikili (BCD) olarak gösterilir. Her iki taraf da en belirgin basamağından en küçüğüne doğru soldan sağa yazılır.

Bits                 =>  Decimal         (Digit range)
a b c d e f 0 g h i  =>  0abc 0def 0ghi  (0-7) (0-7) (0-7)
a b c d e f 1 0 0 i  =>  0abc 0def 100i  (0–7) (0–7) (8–9)
a b c g h f 1 0 1 i  =>  0abc 100f 0ghi  (0–7) (8–9) (0–7)
g h c d e f 1 1 0 i  =>  100c 0def 0ghi  (8–9) (0–7) (0–7)
g h c 0 0 f 1 1 1 i  =>  100c 100f 0ghi  (8–9) (8–9) (0–7)
d e c 0 1 f 1 1 1 i  =>  100c 0def 100i  (8–9) (0–7) (8–9)
a b c 1 0 f 1 1 1 i  =>  0abc 100f 100i  (0–7) (8–9) (8–9)
x x c 1 1 f 1 1 1 i  =>  100c 100f 100i  (8–9) (8–9) (8–9)

Görev

10 DPD bit, 3 ondalık basamağa dönüştürün.

Test durumları

DPD           Decimal
0000000101    005
0001100011    063
0001111001    079
0000011010    090
0001011110    098
1010111010    592
0011001101    941
1100111111    879
1110001110    986
0011111111    999
1111111111    999  * Output is same regardless of the `x` bits

Giriş

Varsayılan giriş formatı 10 bitlik bir listedir. Bitler yukarıdaki tam sırayı veya tam tersini izlemelidir. Bunun yerine eşdeğer bir dize veya tamsayı gösterimi kullanmayı seçebilirsiniz. Diğer zorluklarımın aksine iç içe yapıların yeniden sıralanması veya kullanılması yasaktır. .

Giriş [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]için aşağıdaki formatlara izin verilir:

  • Bitlerin listesi: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
  • Dize: "1100010100"
  • İkili tamsayı: 788veya0b1100010100
  • Ondalık tam sayı: 1100010100
  • Tersine [0, 0, 1, 0, 1, 0, 0, 0, 1, 1]çevrildi : ve yukarıdaki diğer formatlarda ters

Aşağıdaki formatlara izin verilmemektedir:

  • Bitlerin keyfi yeniden sıralanması: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]
  • İç içe yapılar: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]]veya[0b110, 0b001, 0b0100]

Çıktı

Varsayılan çıkış formatı 3 ondalık basamağın listesidir. Her hane, bir tam sayı veya bir karakter olan 0 ila 9 olarak gösterilmelidir. Girişte olduğu gibi dize veya tamsayı gösterimi seçebilirsiniz. Tamsayı gösterimi seçerseniz, baştaki sıfırlar ihmal edilebilir.

Puanlama ve kazanan kriter

Standart kuralları geçerlidir. Bayt cinsinden en kısa program veya işlev her dil için kazanır.

Yanıtlar:


12

JavaScript (ES6), 112 bayt

Bu kısa versiyon için tüm krediler @nwellnhof 'a gider.

Bir tamsayı olarak girdi alır. Üç ondalık basamaklı bir dizi döndürür.

n=>[(x=n>>4,y=x>>3,q=n/2&55,p=q%8)>5&&q-39?8|y&1:y,(p&5^5?x&6:q-23?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p%q<7?y&6:8)|n&1]

Çevrimiçi deneyin!


JavaScript (ES6), 118 117 bayt

Bir tamsayı olarak girdi alır. Üç ondalık basamaklı bir dizi döndürür.

n=>[(x=n>>4&7,y=n>>7,p=n/2&7)>5&&p<7|x/2^2?8|y&1:y,(p<7?p-5?x:8:x/2^1?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p<7|x<2?y&6:8)|n&1]

Çevrimiçi deneyin!

Nasıl?

'Resmi' algoritmayı uygulamaya çalışmak yerine, bu kod beklenen sonuçlarda bulunabilecek modellerin bir tür tersine mühendislik yöntemine dayanmaktadır.

n tamsayı n göz önüne alındığında , biz hesaplar:

x=n16mod8y=n128p=n2mod8

Örnek: ilk hane (yüzlerce)

x     | 0                | 1                | 2                | 3               
n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
p     | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
------+------------------+------------------+------------------+-----------------
y = 0 | 0000000000008888 | 0000000000008888 | 0000000000008888 | 0000000000008888
y = 1 | 1111111111119999 | 1111111111119999 | 1111111111119999 | 1111111111119999
y = 2 | 2222222222228888 | 2222222222228888 | 2222222222228888 | 2222222222228888
y = 3 | 3333333333339999 | 3333333333339999 | 3333333333339999 | 3333333333339999
y = 4 | 4444444444448888 | 4444444444448888 | 4444444444448888 | 4444444444448888
y = 5 | 5555555555559999 | 5555555555559999 | 5555555555559999 | 5555555555559999
y = 6 | 6666666666668888 | 6666666666668888 | 6666666666668888 | 6666666666668888
y = 7 | 7777777777779999 | 7777777777779999 | 7777777777779999 | 7777777777779999

x     | 4                | 5                | 6                | 7               
n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
p     | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
------+------------------+------------------+------------------+-----------------
y = 0 | 0000000000008800 | 0000000000008800 | 0000000000008888 | 0000000000008888
y = 1 | 1111111111119911 | 1111111111119911 | 1111111111119999 | 1111111111119999
y = 2 | 2222222222228822 | 2222222222228822 | 2222222222228888 | 2222222222228888
y = 3 | 3333333333339933 | 3333333333339933 | 3333333333339999 | 3333333333339999
y = 4 | 4444444444448844 | 4444444444448844 | 4444444444448888 | 4444444444448888
y = 5 | 5555555555559955 | 5555555555559955 | 5555555555559999 | 5555555555559999
y = 6 | 6666666666668866 | 6666666666668866 | 6666666666668888 | 6666666666668888
y = 7 | 7777777777779977 | 7777777777779977 | 7777777777779999 | 7777777777779999

Algoritma:

  • Eğer p<6 , var d=y
  • Eğer p=6 , d=8+(ymod2)
  • Eğer p=7 AND (x<4 OR x>5) , biz d=8+(ymod2)
  • Eğer p=7 AND (x=4 OR x=5) , elimizdeki d=y

JS kodu olarak:

p > 5 && p < 7 | x / 2 ^ 2 ? 8 | y & 1 : y

1
Yaklaşımınız, başka bir geçici değişken kullanan C cevabımla benzerlik gösteriyor. İlk C çözümümü biraz daha golf oynadıktan sonra, JavaScript'e bir bağlantı noktası 112 bayta neden oluyor .
nwellnhof

10

Python 3 , 229 ... 97 96 bayt

lambda a:[[a&6,a>>4&6,a>>7&6,8][b"  eW7B]Oys"[~a&8or~a&6or~6|a>>4]%x&3]|a>>x%9&1for x in[7,4,9]]

Çevrimiçi deneyin!

@Xnor tarafından -4 bayt

-6 bytes by @nwellnhof

biçimlendirilmiş:

h = lambda a:[
    [a&6, a>>4&6, a>>7&6, 8][              List to take high bits from
        b"  eW7B]Oys"[                     10 char string; where to get high bits for
                                             indicator values 1-8. 0th,1st chars not used.
            ~a&8 or ~a&6 or ~6|a>>4]       Compute indicator (by @nwellnhof)
        %x&3]                              High bits of each digit
    | a >> x%9 & 1                         bitwise OR with low bit of each digit
    for x in [7,4,9]]

açıklama

Aslında bunu Jelly'te uygulamak istediğim için, buradaki çoğu cevaptan farklı bir yaklaşım benimsiyorum; bu basit ve belki de bir golf dili için uygun. Golf fonksiyonu bir tamsayı alırken, girişin bit listesi olmasını sağlayın [a0,a1,...,a9]. Sonra girişten üç değer türetebiliriz

  • Düşük bit [a2,a5,a9]: Bunlar her zaman [d0,d1,d2]sırasıyla düşük bit olacaktır.
  • Yüksek bitler [2*a0a1,2*a3a4,2*a7a8,8]: Her basamağın yüksek bitleri bunlardan biri olacaktır.
  • Gösterge [a3,a4,a5,a7,a8], her bir basamağın yüksek bitlerinin nasıl alınacağını belirleyen bit. Göstergeyi şu şekilde hesaplıyoruz (1 ile 8 arasında):
    • A5 == 0 ise, gösterge 8'dir (başlangıçta 0'dır, ancak 8 kullanılması yerine bayt kaydeder)
    • A3 ve a4 ise, gösterge 6 - 2 * a3a4 olur
    • Aksi halde gösterge 2 * a7a8 + 1'dir (aslında negatif sayı olarak hesaplanır).

Ardından, n. Basamak, high_bits[arr[indicator][n]] | low_bits[n]bir dizgede sıkıştırılmış aşağıdaki tablodaki gibi zarif bir şekilde hesaplanabilir .

arr = [
    [0,1,2],
    [3,1,2],
    [1,3,2],
    [2,1,3],
    [2,3,3],
    [3,2,3],
    [3,3,2],
    [3,3,3]
]

1
İle b"..."dönüştürme yerine bir bytestring kullanabilirsiniz ord.
xnor

@nwellnhof Ha, ben de aynı şeyi buldum! Yine de size kredi verir.
lirtosiast

b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)] başka bir dört bayt kaydeder.
nwellnhof

@nwellnhof Bir modulo zincirinin buraya gitmenin yolu olduğunu düşünüyorum, ancak sizinki değilse kesinlikle işe yarar.
lirtosiast

9

JavaScript (Node.js) , 126 119 117 112 111 bayt

(a,b,c,d,e,f,g,h,i,j)=>[(g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c,(g&i?h+e-3?8:b:e)+f,(g?h<i?e:h>i*e?b:8:h*4+i*2)+j]

Çevrimiçi deneyin!

-5 bayt teşekkürler @tsh (ve 2 tek başıma) Böylece lbeklediğimden daha fazla çaba harcayabilir .

@ Tsh tekniğini kullanarak -2 bayt daha!

-5 bayt teşekkürler @Arnauld

-1 bayt teşekkürler @Neil

10 bitlik bir liste halinde giriş yapın (10 bağımsız değişken olarak), 3 basamaklı bir liste halinde çıktı alın.


1
(!i|!d|e)-> i+l!=5; (d|e|!h)->h+l!=1
tsh

1
(g?h-i|h&!e?h?b:e:8:h*4+i*2)-> (g?h<i?e:h>i*e?b:8:h*4+i*2)başka bir bayt kaydeder. (Bu sefer kontrol ettim ...)
Neil

8

C (gcc) , 138 129 bayt

f(w){int t=w/2&55,s=t%8,v=w/16,u=v/8;w=((s<6|t==39?u:8|u%2)*10+v%2+(s&5^5?v&6:t-23?8:u&6))*10+w%2+(s<5?s*2:s<6?v&6:s%t<7?u&6:8);}

Çevrimiçi deneyin!

İlk önce bazı bitleri değişkenlere ekler svet böylece dönüşüm tablosunun sekiz satırı şöyle tanımlanabilir:

1.  s < 4              u v w¹
2.  s = 4              u v 8¹
3.  s = 5              u 8 v
4.  s = 6              8 v u
5.  s = 7, t =  7      8 8 u
6.  s = 7, t = 23      8 u 8
7.  s = 7, t = 39      u 8 8
8.  s = 7, t = 55      8 8 8

¹ Can be computed with s*2

Daha sonra kurar uve vbölümler (sağ kaymalar), böylece ile u, vve giriş wpozisyonlarında 0-2 alt üç BCD bit içerir. Gerisi sve bağlı olarak biraz karışıktır t. İki önemli numara:

s&5^5  // Rows 1, 2 and 4.
s%t<7  // Rows 1-5.

Shieru Asakoto'nun Javascript çözümünün limanı sadece 124 bayttır :

f(a,b,c,d,e,f,g,h,i,j){a=(((g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c)*10+(g&i?h+e-3?8:b:e)+f)*10+(g?h-i|h&!e?h?b:e:8:h*4+i*2)+j;}

Çevrimiçi deneyin!


Sanırım kısaltılabilir:f(b){int a=b/2%8,e=b&110,c=b/16,d=c/8;b=10*(10*(d%2|(6>a|78==e?d:8))+c%2+(3<a&a%2?e-46?8:d&6:c&6))+b%2+(4>a?b&6:a-5?a-6&&e-14?8:d&6:c&6)};
MCCCS

@CCCS Kodunuz 138 byte gibi görünüyor.
nwellnhof

5

Ruby , 153 ... 119 117 bayt

->n{n+=n&896;a,b,c=n&1536,n&96,n&14;"%x"%n+=c<9?0:2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}

Çevrimiçi deneyin!

Nasıl çalışır:

->n{n+=n&896;

Bu başlangıç ​​noktasıdır: kalıpların çoğu için işe yarayan 3 bit sola kaydırarak BCD'ye dönüştürün.

a,b,c=n&1536,n&96,n&14;

Her bir ucun orta bitini alın (ve üçüncü ucun bir ekstra bitini, ancak en az anlamlı biti maskeleyin).

"%x"%n+=c<9?0

Eğer üçüncü hane 10'dan küçükse (9'dan az olduğu için LSB'yi hiç umursamadık çünkü) belirledik: bu düz BCD'dir, hex'i hiçbir şey değiştirmeden çıkarabiliriz

:2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}

Aksi taktirde, etrafta bitleri kaydırarak ve istediğimiz sonucu elde edene kadar sihirli sayılar ekleyerek biraz kara büyü yapın.


5

Retina 0.8.2 , 191 181 bayt

(...)(...)
:$1,$2;
..(.),11(.);111
100$1,100$2;100
(10|(..)(.,)01)(.);111
100$3$2$4;100
(..)(.),(00.);111
100$2,1$3;0$1
(..)((.{5});110|(.);101)
100$3$4;$1
1
01
+`10
011
.0+(1*)
$.1

Çevrimiçi deneyin! Link, test durumlarını içerir. Düzenleme: Gerekli olduğu durumlar dışında 4 bite kadar sayıları doldurmadan 10 bayt kurtardı. Açıklama:

(...)(...)
:$1,$2;

Ayırıcıları yerleştirin, böylece her basamak ayrı ayrı ondalık basamağa dönüştürülebilir. Bu, dönüşüm tablosundaki ilk iki vakayı etkin biçimde ele alır.

..(.),11(.);111
100$1,100$2;100

Son (sekizinci) vakayı dönüşüm tablosunda kullanın.

(10|(..)(.,)01)(.);111
100$3$2$4;100

Altıncı ve yedinci vakaları dönüşüm tablosunda kullanın.

(..)(.),(00.);111
100$2,1$3;0$1

Beşinci durumu dönüşüm tablosunda kullanın.

(..)((.{5});110|(.);101)
100$3$4;$1

Üçüncü ve dördüncü vakaları dönüşüm tablosunda kullanın.

1
01
+`10
011
.0+(1*)
$.1

Ondalık dönüşüm için ikili gerçekleştirin.


5

Jelly , 51 48 40 39 bayt

&\‘f4;s3ɓạ4ḅ-œ?µ/Ḥ
“MY-€-Y¤©¡‘Dịs3Ḅç+ƭ/

Çevrimiçi deneyin!

Algoritma

Liste endeksleri dışında, bu bölümdeki tüm tamsayılar ikili olarak yazılmıştır.

αβγδεζηθικ[ηη,θι,δε][αβ,δε,θι][γ,ζ,κ] .

  1. ηη=0000000111 ).
  2. ηη=11θι<1110001001 ).
  3. ηη=θι=11δε<11 , tam olarak iki çıkış basamağı yüksektir.
  4. ηη=θι=δε=11

11[ηη,θι,δε]100[αβ,δε,θι]

  1. [[αβ,δε,θι]]
  2. [[100,αβ,δε],[θι]]
  3. [[100,100,αβ],[δε,θι]]=[[100,100,αβ],[δε,11]]
  4. [[100,100,100],[αβ,δε,θι]]=[[100,100,100],[αβ,11,11]]

[γ,ζ,κ][αβγ,δεζ,θικ][100γ,100ζ,100κ] son olarak.

Kalan iki dava benzer, ancak diziler [100,αβ,δε] ve [100,100,αβ] değerlerine göre yeniden düzenlenmeli [θι] ve muhtemelen δε.

İkinci durumda, altı permütasyon [100,αβ,δε] Hangi [100,αβ,δε], [100,δε,αβ], [αβ,100,δε], [αβ,δε,100], [δε,100,αβ], ve [δε,αβ,100].

Hesaplayarak 100-θι, biz harita 00, 01, ve 10 dört, üç ve iki, permütasyonları seçmek [αβ,δε,100], [αβ,100,δε], ve [100,δε,αβ].

İle sonucu sıkıştırdıktan sonra [γ,ζ,κ]aldık [αβγ,δεζ,100κ], [αβγ,100ζ,δεκ]veya [100γ,δεζ,αβκ].

Üçüncü durumda, izinleri (çiftlerle birlikte) [100,100,αβ] Hangi [100,100,αβ], [100,αβ,100], [100,100,αβ], [100,αβ,100], [αβ,100,100] ve [αβ,100,100].

Hesaplayarak (100-θι)-(100-δε)=δε-θι=δε-11, biz harita 00, 01, ve 10 to three, four, and five modulo six, selecting the permutations [100,100,αβ], [100,αβ,100], and [αβ,100,100].

After zipping the result with [γ,ζ,κ], we get [100γ,100ζ,αβκ], [100γ,αβζ,100κ], or [αβγ,100ζ,100κ].

Code

“MY-€-Y¤©¡‘Dịs3Ḅç+ƭ/  Main link. Argument: A (array of 10 bits)

“MY-€-Y¤©¡‘           Array literal; yield [77, 89, 45, 12, 45, 89, 3, 6, 0].
           D          Decimal; yield
                      [[7,7], [8,9], [4,5], [1,2], [4,5], [8,9], [3], [6], [0]].
            ị         Retrieve the elements of A at those indices.
                      Indexing is 1-based and modular, so 1 is the first index, while
                      0 is the last.
             s3       Split the results 2D array of bits into chunks of length 3.
               Ḅ      Convert the 9 arrays of bits from binary to integer.
                ç+ƭ/  Reduce the resulting array (length 3) once by the helper link,
                      then by addition.


&\‘f4;s3ɓạ4ḅ-œ?µ/Ḥ    Helper link. Arguments: B, C (arrays of three integers each)

&\                    Cumulatively reduce B by bitwise AND.
  ‘                   Increment the results by 1.
   f4                 Filter; keep only integers equal to 4.
     ;                Concatenate the result with C.
      s3              Split the result into (one or two) chunks of length 3.
        ɓ      µ/     Reduce the array of chunks by the following chain.
         ạ4               Take the absolute difference of the integers in the right
                          chunk and the integer 4.
           ḅ-             Convert the resulting array from base -1 to integer, i.e.,
                          map [x] to n = x and [x, y] to n = y - x.
             œ?           Take the n-th permutation of the left chunk.
                 Ḥ    Unhalve; multiply the resulting integers by 2.

2

Python 2, 157 bytes

lambda a,b,c,d,e,f,g,h,i,j:[c+[a*4+b*2,8][g*h*~(d*~e*i)],f+[d*4+e*2,8,a*4+b*2][g*i+(d<e)*g*i*h],j+[h*4+i*2,[8,[a*4+b*2,d*4+e*2][h<i]][h^i or(h&i-(d|e))]][g]]

Try it online!


2

Clean, 238 ... 189 bytes

-2 bytes thanks to Neil

import StdEnv
$a b c d e f g h i j=100*(c+2*b+4*a)+10*(f+2*e+4*d)+j+2*i+4*h-2*(h*(99*b+198*a-394)+i*(9*e+18*d+h*(e+2*d-4+(b+2*a-4)*(1-10*e-100*d+110*e*d))-35)-4)*g+0^(e+d)*(2*b+4*a-8*i*h*g)

Try it online!

Takes a 'list' of 10 bits in the form of 10 arguments, using a direct formula to compute the result.


In i*(9*e+19*d+i*...), that second i* looks unnecessary.
Neil

@Neil You're right, it is, thanks.
Οurous

1

Perl 5, 195 bytes

sub f{$n=shift;@p=((map{($n>>$_&3)*2}(8,5,1)),8);for(16390,28935,29005,227791,29108,225788,226803,228863){return 2*$n&256|$n&17|$p[$_>>4&3]<<8|$p[$_/4&3]<<4|$p[$_&3]if($_>>12&$n/2)==($_>>6&63);}}

Try it online

I know 195 bytes is far too much for this contest, but I had no idea how to further compress the Perl code. Suggestions?

Explanation of the code

In a more readable version, the code intention should become apparent:

sub dpd {
  my $n = shift;
  my $v=2*($n&128)|$n&17;
  my @p=((map{($n>>$_&3)*2}(8,5,1)),8);
  for (16390,28935,29005,227791,29108,225788,226803,228863) {
    return $v |$p[$_>>4&3]<<8|$p[$_>>2&3]<<4|$p[$_&3]
      if(($_>>12&$n/2)==($_>>6&63));
  }
}

In the rules for DPD encoding, each line is encoded into a 18 bit value, segmentation into (6,6,(2,2,2)) bits.

  • The first 6 bits are an appropriate bit mask for the bits 1 (=h) to 6 (=d) of the input (bit 4 = f is redundant, but it simplifies the evaluation code to have it included).
  • The next 6 bits are the value bits for this bit mask. The values are checked on all places where the bit mask has a 1 value.
  • The following 3*2 bits contain the indices for the array @p for the 3-bit sequences which are to spliced into bits 11-9, 7-5 and 3-1 of the result.
  • The array @p is constructed from bits 9-8, 6-5, 3-2 of the input, and the number 8 as fourth member
  • The bits at position 7,4 and 0 of the input are transferred directly into bits 8,4 and 0 of the result.

For example, the first number in the list, 16390, which is 100000000000110 as a bit field, carries the following information:

000100 : bit mask says: only consider bit 3 of the input
000000 : bit values say: bit 3 should be 0
00     : use '0ab' as higher bits of first digit
01     : use '0de' as higher bits of second digit
10     : use '0gh' as higher bits of third digit

1

05AB1E, 84 bytes

Port of KimOyhus' answer to 05AB1E.

•4’7þ2Ô€iΘEuĆΣk4Ѐ:ΘΛs‡CaΔʒì₁3¶rdiMß¡þи иø-˜)Â∍DY—WûQ@—Mā}Γ¤ÒÙ]p•44в2ôvÐyèP≠«}4ôC3.£

Try it online!

Rough explanation:

•yadayada•44в2ô   # encoded list of nand gates
v                 # for each gate
 ÐyèP≠            # compute the output of the gate
      «           # append it to the input
       }          # end of the loop
4ô                # split the list of bits in groups of 4
  C               # convert each from binary to decimal
   3.£            # keep the last 3 numbers
                  # implicit output

0

05AB1E , 104 103 101 bayt

•3γã•S£©4èUXтÌ‹XSPVY®2èDˆTQ*~i0®нëт}®1èY¯`*i0®нëY_Xт>Ê*i0¯`ëт]®3èY¯`_*X110Q~i0®нëXт›iYiтë0¯`ëX]®θJ4ôC

Kesinlikle bu tür bir meydan okuma için doğru dil değil, ah ah ..
dize olarak girin, üç basamaklı bir liste halinde çıktı alın.

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

Açıklama:

Dikkate alınması gereken aşağıdaki sekiz senaryo var:

     1st 2nd 3rd 4th 5th 6th                          1st digit    2nd digit    3rd digit
1.   ab  c   de  f   0gh i   →   0abc 0def 0ghi   →   '0'+1st 2nd  '0'+3rd 4th  5th     6th
2.   ab  c   de  f   100 i   →   0abc 0def 100i   →   '0'+1st 2nd  '0'+3rd 4th  5th     6th
3.   ab  c   gh  f   101 i   →   0abc 100f 0ghi   →   '0'+1st 2nd  '100'   4th  '0'+3rd 6th
4.   gh  c   de  f   110 i   →   100c 0def 0ghi   →   '100'   2nd  '0'+3rd 4th  '0'+1st 6th
5.   gh  c   00  f   111 i   →   100c 100f 0ghi   →   '100'   2nd  '100'   4th  '0'+1st 6th
6.   de  c   01  f   111 i   →   100c 0def 100i   →   '100'   2nd  '0'+1st 4th  '100'   6th
7.   ab  c   10  f   111 i   →   0abc 100f 100i   →   '0'+1st 2nd  '100'   4th  '100'   6th
8.   xx  c   11  f   111 i   →   100c 100f 100i   →   '100'   2nd  '100'   4th  '100'   6th

Öncelikle (örtük) girdisini büyüklükteki parçalara böler [2,1,2,1,3,1]ve bu listeyi kayıt defterinde saklarım:

3γã•     # Push compressed integer 212131
     S    # Convert it to a list of digits
      £   # Split the (implicit) input in chunks of that size
       ©  # Store it in the register (without popping)

Bunun neden •3γã•olduğunu anlamak için bu 05AB1E ucuna bakın ( büyük tam sayıların sıkıştırılması nasıl yapılır? )212131

Şimdi ilk önce çıktının ilk basamağı için 0 ve 1'leri yapacağız. Senaryolar 1,2,3,7 kullanım '0'+1st+2nd; ve 4,5,6,8 senaryolarının kullanımı '100'+2nd:

4è                  # Take the 5th item of the list
  U                 # Pop and store it in variable `X`
XтÌ‹                #  Check if `X` is below 102
                ~   # OR
   XSP              #  `X` is equal to 111
      VY            #  And store that result in variable `Y`
               *    #  and
        ®2è         #  Get the 3rd item from the list of the register
           Dˆ       #  Push it to the global array
             TQ     #  And check if it's equal to 10
i                   # If the combined check above is truthy (exactly 1):
 0                  #  Push 0 to the stack
 ®н                 #  Push the 1st item of the list to the stack
ë                   # Else:
 т                  #  Push 100 to the stack
}                   # Close the if-else
®1è                 # And push the 2nd item of the list to the stack

Sonra çıktının ikinci basamağı için 0 ve 1'leri yapacağız. Senaryolar 1,2,4 kullanım '0'+3rd+4th; 3,5,7,8 senaryoları '100'+4th; ve senaryo 6 '0'+1st+4thşunları kullanır :

Y                # Push `Y` (check if `X` equals 111)
   *             # and
 ¯`              # Push the item from the global array (3rd item of the list)
i                # If both checks above are truthy (exactly 1):
 0               #  Push 0 to the stack
 ®н              #  Push the 1st item of the list to the stack
ë                # Else:
 Y_              #  Push inverted `Y` (check if `X` does NOT equal 111)
       *         #  and
   Xт>Ê          #  Check if `X` (5th item of the list) does NOT equal 101
 i               #  If both checks above are truthy (exactly 1):
  0              #   Push 0 to the stack
  ¯`             #   Push the item from the global array (3rd item of the list)
 ë               #  Else:
  т              #   Push 100 to the stack
]                # Close both if-else cases
®3è              # And push the 4th item of the list to the stack

Sonra çıktının üçüncü basamağı için 0 ve 1'leri yapacağız. Senaryolar 1,2 kullanımı 5th+6th; senaryo 3 kullanır '0'+3rd+6th; 4,5 senaryo kullanımı '0'+1st+6th; ve 6,7,8 senaryolarının kullanımı '100'+6th:

Y           #  Push `Y` (check if `X` equals 111)
    *       #  and
 ¯`_        #  Check if the item from the global array (3rd item of the list) is exactly 0
         ~  # OR
    X110Q   #  Check if `X` (5th item of the list) equals 110
i           # If the combined check above is truthy (exactly 1):
 0          #  Push 0 to the stack
 ®н         #  Push the 1st item of the list to the stack
ë           # Else:
 Xт›i       #  If `X` (5th item of the list) is larger than 100 (so 101/110/111):
     Yi     #   If `Y` (if `X` equals 111):
       т    #    Push 100 to the stack
      ë     #   Else:
       0    #    Push 0 to the stack
       ¯`   #    Push the item from the global array (3rd item of the list)
    ë       #  Else:
     X      #   Push `X` (5th item of the list) to the stack
]           # Close all if-else cases
®θ          # And push the last (6th) item of the list to the stack

Şimdi yığında bütün 0'lar ve 1'ler var, bu yüzden onu üç çıkış hanesine dönüştürebiliriz:

J     # Join the entire stack together
 4ô   # Split it into parts of size 4
   C  # Convert each part from binary to an integer (and output implicitly)
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.