Gęsto upakowany ułamek dziesiętny (DPD) do dziesiętnego

26

Dla fanów gry Nandgame: wypróbuj DPD również dziesiętnie w bramkach logicznych !

tło

Gęsto upakowane miejsca dziesiętne (DPD) to sposób na skuteczne przechowywanie cyfr dziesiętnych w formacie binarnym. Przechowuje trzy cyfry dziesiętne (od 000 do 999) w 10 bitach, co jest znacznie wydajniejsze niż naiwny BCD (który przechowuje jedną cyfrę w 4 bitach).

Notacje

  • Małe litery ato isą bity, które są kopiowane do reprezentacji dziesiętnej.
  • 0i 1są dokładnymi bitami we wzorcach bitów wejściowych lub wyjściowych.
  • x bity są ignorowane podczas konwersji.

Tabela konwersji

Poniżej znajduje się tabela konwersji z 10 bitów DPD na trzy cyfry dziesiętne. Każda cyfra dziesiętna jest reprezentowana jako 4-bitowy układ binarny (BCD). Obie strony są pisane od lewej do prawej, od najbardziej znaczącej cyfry do najmniejszej.

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)

Zadanie

Konwertuj 10 bitów DPD na 3 cyfry dziesiętne.

Przypadki testowe

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

Wkład

Domyślnym formatem wejściowym jest lista 10 bitów. Bity powinny być zgodne z dokładną kolejnością powyżej lub odwrotnie. Zamiast tego możesz użyć równoważnego ciągu lub liczby całkowitej. W przeciwieństwie do innych moich wyzwań, zmiana kolejności lub użycie struktur zagnieżdżonych jest niedozwolone .

Dla danych wejściowych [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]dozwolone są następujące formaty:

  • Lista bitów: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
  • Strunowy: "1100010100"
  • Binarna liczba całkowita: 788lub0b1100010100
  • Liczba dziesiętna: 1100010100
  • Odwrócone: [0, 0, 1, 0, 1, 0, 0, 0, 1, 1]i odwrócone w dowolnych innych formatach powyżej

Następujące formaty NIE są dozwolone:

  • Dowolna zmiana kolejności bitów: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]
  • Struktury zagnieżdżone: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]]lub[0b110, 0b001, 0b0100]

Wydajność

Domyślny format wyjściowy to lista 3 cyfr dziesiętnych. Każda cyfra powinna być reprezentowana od 0 do 9, albo liczbą całkowitą, albo znakiem. Tak jak na wejściu, możesz wybrać reprezentację ciągu lub liczby całkowitej. Jeśli wybierzesz reprezentację liczb całkowitych, zera wiodące można pominąć.

Kryterium punktacji i wygranej

Obowiązują standardowe zasady . Wygrywa najkrótszy program lub funkcja w bajtach dla każdego języka.

Bubbler
źródło

Odpowiedzi:

12

JavaScript (ES6), 112 bajtów

Podziękowania dla tej krótszej wersji należą się do @nwellnhof.

Pobiera dane wejściowe jako liczbę całkowitą. Zwraca tablicę trzech cyfr dziesiętnych.

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]

Wypróbuj online!


JavaScript (ES6), 118 117 bajtów

Pobiera dane wejściowe jako liczbę całkowitą. Zwraca tablicę trzech cyfr dziesiętnych.

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]

Wypróbuj online!

W jaki sposób?

Zamiast próbować zastosować „oficjalny” algorytm, kod ten opiera się na pewnego rodzaju inżynierii wstecznej wzorców, które można znaleźć w oczekiwanych wynikach.

Biorąc pod uwagę liczbę całkowitą wejściową n , obliczamy:

x=n16mod8y=n128p=n2mod8

Przykład: pierwsza cyfra (setki)

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

Algorytm:

  • Jeśli , mamyp<6d=y
  • Jeśli , mamyp=6d=8+(ymod2)
  • Jeśli , mamyp=7 AND (x<4 OR x>5)d=8+(ymod2)
  • Jeśli , mamyp=7 AND (x=4 OR x=5)d=y

Jako kod JS:

p > 5 && p < 7 | x / 2 ^ 2 ? 8 | y & 1 : y
Arnauld
źródło
1
Twoje podejście jest podobne do mojej odpowiedzi C, która wykorzystuje inną zmienną tymczasową. Po nieco bardziej golfowym przejściu na moje początkowe rozwiązanie C, port do JavaScript daje 112 bajtów .
nwellnhof,
10

Python 3 , 229 ... 97 96 bajtów

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]]

Wypróbuj online!

-4 bajty przez @xnor

-6 bajtów autorstwa @nwellnhof

Sformatowany:

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]]

Wyjaśnienie

Ponieważ początkowo chciałem to zaimplementować w Jelly, podchodzę do innego rozwiązania w stosunku do większości odpowiedzi tutaj, które jest proste i być może pasuje do języka golfa. Chociaż funkcja gry w golfa przyjmuje liczbę całkowitą, niech wejście będzie w postaci listy bitowej [a0,a1,...,a9]. Następnie możemy wyprowadzić trzy wartości z danych wejściowych

  • Niskie bity [a2,a5,a9]: zawsze będą to odpowiednio niskie bity [d0,d1,d2].
  • Wysokie bity [2*a0a1,2*a3a4,2*a7a8,8]: Wysokie bity każdej cyfry będą jednym z nich.
  • Bity wskaźnika [a3,a4,a5,a7,a8]określające, jak uzyskać wysokie bity każdej cyfry. Obliczamy wskaźnik (od 1 do 8) w następujący sposób:
    • Jeśli a5 == 0, wskaźnik wynosi 8 (pierwotnie 0, ale użycie 8 zamiast tego zapisuje bajt)
    • Jeżeli a3 nand a4, wskaźnik wynosi 6 - 2 * a3a4
    • W przeciwnym razie wskaźnik wynosi 2 * a7a8 + 1 (faktycznie obliczony jako liczba ujemna).

Następnie n-ta cyfra może być elegancko obliczona jak high_bits[arr[indicator][n]] | low_bits[n]w poniższej tabeli, która jest skompresowana w ciąg.

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]
]
lirtosiast
źródło
1
Możesz użyć bajtowania, b"..."aby zastąpić konwersję ord.
xnor
@nwellnhof Ha, właśnie znalazłem to samo! I tak cię zaliczy.
lirtosiast
b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)]oszczędza kolejne cztery bajty.
nwellnhof,
@nwellnhof Myślę, że droga do modulo jest tutaj, ale jeśli nie, twój z pewnością by działał.
lirtosiast
9

JavaScript (Node.js) , 126 119 117 112 111 bajtów

(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]

Wypróbuj online!

-5 bajtów dzięki @tsh (i 2 przez siebie) Więc lmogę zrobić więcej wysiłku, niż się spodziewałem.

-2 więcej bajtów przy użyciu techniki @ tsh!

-5 bajtów dzięki @Arnauld

-1 bajtów dzięki @Neil

Dane wejściowe jako lista 10 bitów (jako 10 argumentów), dane wyjściowe jako lista 3 cyfr.

Shieru Asakoto
źródło
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)zapisuje kolejny bajt. (Tym razem sprawdziłem ...)
Neil,
8

C (gcc) , 138 129 bajtów

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);}

Wypróbuj online!

Pierwszy ekstraktów niektórych bitów w zmiennych sa t, tak że osiem rzędów z tabeli konwersji mogą być określane:

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

Następnie ustawia się ui vpodziałami (prawa zmiany), tak że u, voraz wkład wzawiera trzy niższe BCD bitów w pozycjach 0-2. Reszta jest nieco tasowana w zależności od si t. Dwie ważne sztuczki to:

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

Port rozwiązania JavaScript Shieru Asakoto ma tylko 124 bajty :

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;}

Wypróbuj online!

nwellnhof
źródło
Myślę, że można go skrócić do: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,
@MCCCS Twój kod wydaje się mieć również 138 bajtów.
nwellnhof
5

Ruby , 153 ... 119 117 bajtów

->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]}

Wypróbuj online!

Jak to działa:

->n{n+=n&896;

To jest punkt początkowy: przekonwertuj na BCD, przesuwając 3 bity w lewo, co działa w przypadku większości wzorów.

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

Zdobądź środkowe bity każdego skórka (i jeden dodatkowy bit trzeciego skórka, ale zamaskuj najmniej znaczący bit).

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

Jeśli trzecia cyfra jest mniejsza niż 10 (mniejsza niż 9, ponieważ i tak nigdy nie dbaliśmy o LSB), ustawiamy: jest to zwykły BCD, możemy wyprowadzić hex bez zmiany czegokolwiek

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

W przeciwnym razie wykonaj czarną magię, przesuwając kawałki i dodając magiczne liczby, aż uzyskamy pożądany rezultat.

GB
źródło
5

Retina 0.8.2 , 191 181 bajtów

(...)(...)
:$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

Wypróbuj online! Link zawiera przypadki testowe. Edycja: Zapisano 10 bajtów, nie dopełniając cyfr do 4 bitów, chyba że to konieczne. Wyjaśnienie:

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

Wstaw separatory, aby każdą cyfrę można było przekonwertować osobno na dziesiętne. To skutecznie obsługuje pierwsze dwa przypadki w tabeli konwersji.

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

Obsługuj ostatni (ósmy) przypadek w tabeli konwersji.

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

Obsługuj szósty i siódmy przypadek w tabeli konwersji.

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

Obsługuj piąty przypadek w tabeli konwersji.

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

Obsługuj trzeci i czwarty przypadek w tabeli konwersji.

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

Wykonaj konwersję binarną na dziesiętną.

Neil
źródło
5

Galaretka , 51 48 40 39 bajtów

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

Wypróbuj online!

Algorytm

Z wyjątkiem indeksów list, wszystkie liczby całkowite w tej sekcji są zapisywane binarnie.

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

  1. ηη=0000000111
  2. ηη=11θι<1110001001
  3. ηη=θι=11δε<11
  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κ]

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

[100,αβ,δε][100,αβ,δε][100,δε,αβ][αβ,100,δε][αβ,δε,100][δε,100,αβ][δε,αβ,100]

100θι000110[αβ,δε,100][αβ,100,δε][100,δε,αβ]

[γ,ζ,κ][αβγ,δεζ,100κ][αβγ,100ζ,δεκ][100γ,δεζ,αβκ]

[100,100,αβ][100,100,αβ][100,αβ,100][100,100,αβ][100,αβ,100][αβ,100,100][αβ,100,100]

(100θι)(100δε)=δεθι=δε11000110[100,100,αβ][100,αβ,100][αβ,100,100]

[γ,ζ,κ][100γ,100ζ,αβκ][100γ,αβζ,100κ][αβγ,100ζ,100κ]

Kod

“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.
Dennis
źródło
2

Python 2 , 157 bajtów

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]]

Wypróbuj online!

TFeld
źródło
2

Czysty , 238 ... 189 bajtów

-2 bajty dzięki Neilowi

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)

Wypróbuj online!

Pobiera „listę” 10 bitów w postaci 10 argumentów, używając bezpośredniej formuły do ​​obliczenia wyniku.

Obrzydliwe
źródło
W i*(9*e+19*d+i*...), ten drugi i*wygląda niepotrzebne.
Neil
@Neil Masz rację, dziękuję.
Οurous
1

Perl 5, 195 bajtów

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);}}

Wypróbuj online

Wiem, że 195 bajtów to zdecydowanie za dużo dla tego konkursu, ale nie miałem pojęcia, jak dalej kompresować kod Perla. Propozycje?

Objaśnienie kodu

W bardziej czytelnej wersji intencja kodu powinna stać się widoczna:

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));
  }
}

W regułach kodowania DPD każda linia jest kodowana na wartość 18-bitową, segmentacja na (6,6, (2,2,2)) bity.

  • Pierwsze 6 bitów jest odpowiednią maską bitów dla bitów 1 (= h) do 6 (= d) wejścia (bit 4 = f jest redundantny, ale upraszcza kod obliczeniowy, aby go uwzględnić).
  • Następne 6 bitów to bity wartości dla tej maski bitowej. Wartości są sprawdzane we wszystkich miejscach, w których maska ​​bitowa ma wartość 1.
  • Poniższe 3 * 2 bity zawierają wskaźniki dla tablicy @pdla 3-bitowych sekwencji, które mają być splatane do bitów 11-9, 7-5 i 3-1 wyniku.
  • Tablica @pjest zbudowana z bitów 9-8, 6-5, 3-2 danych wejściowych i liczby 8jako czwartego elementu
  • Bity w pozycjach 7,4 i 0 wejścia są przenoszone bezpośrednio do bitów 8,4 i 0 wyniku.

Na przykład pierwszy numer na liście 16390, który jest 100000000000110polem bitowym, zawiera następujące informacje:

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
rplantiko
źródło
1

05AB1E , 84 bajty

Odpowiedź portu KimOyhus na 05AB1E.

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

Wypróbuj online!

Szorstkie wyjaśnienie:

•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
Ponury
źródło
0

05AB1E , 104 103 101 bajtów

•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

Zdecydowanie nie jest to odpowiedni język dla tego rodzaju wyzwań, ale cóż…
Wpisz jako ciąg, wyślij jako listę trzech cyfr.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

Do rozważenia jest osiem następujących scenariuszy:

     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

Najpierw podzielę (niejawne) dane wejściowe na kawałki wielkości [2,1,2,1,3,1]i przechowuję tę listę w rejestrze:

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)

Zobacz moją wskazówkę 05AB1E (rozdział Jak kompresować duże liczby całkowite? ), Aby zrozumieć, dlaczego tak •3γã•jest212131

Teraz najpierw zbudujemy cyfry 0 i 1 dla pierwszej cyfry wyniku. Wykorzystanie scenariuszy 1,2,3,7 '0'+1st+2nd; i scenariusze 4,5,6,8 użycia '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

Następnie zbudujemy cyfry 0 i 1 dla drugiej cyfry wyniku. Wykorzystanie scenariuszy 1,2,4 '0'+3rd+4th; wykorzystanie scenariuszy 3,5,7,8 '100'+4th; a scenariusz 6 wykorzystuje '0'+1st+4th:

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

Następnie zbudujemy cyfry 0 i 1 dla trzeciej cyfry wyniku. Scenariusze użycia 1,2 5th+6th; scenariusz 3 zastosowania '0'+3rd+6th; wykorzystanie scenariuszy 4,5 '0'+1st+6th; i scenariusze 6,7,8 użycie '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

Teraz mamy wszystkie zera i jedynki na stosie, więc możemy przekonwertować je na trzy cyfry wyjściowe:

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)
Kevin Cruijssen
źródło