Grid Based Digital Logic (Duodyadic Tiles)


33

Le tessere duodadiche sono tipi di blocchi funzionali quadrati che accettano due ingressi, uno dal lato superiore e uno dal lato sinistro, e hanno due uscite, uno sul lato destro e uno sul lato inferiore. Ciascuno dei loro output è una funzione separata di entrambi i loro input.

Ad esempio, se #rappresenta una piastrella generico, l'uscita di destra Rè una funzione fdegli ingressi Te L, e l'uscita inferiore Bè un'altra funzione gdi Te L:

 T
L#R         R = f(T, L)
 B          B = g(T, L)

(Le tessere sono chiamate "duo" poiché ci sono due funzioni e "diadica" poiché entrambe le funzioni hanno due argomenti .)

Le tessere possono quindi essere composte insieme su una griglia, le uscite di una tessera vanno direttamente negli ingressi delle tessere vicine. Qui ad esempio, l'output destro di sinistra #va nell'input sinistro di destra #:

 AB         D = f(f(A, C), B)
C##D        E = g(A, C)
 EF         F = g(f(A, C), B)

Puoi immaginare che, dato un insieme di tessere duodadiche, ognuna con funzionalità specifiche, si possano creare composizioni complesse (e potenzialmente utili).

In questa sfida, ci occuperemo solo dell'insieme tradizionale di dieci riquadri duodadici basati sulla logica , in cui tutti gli ingressi e le uscite sono numeri binari a bit singolo (zeri o uno). Useremo un carattere ASCII separato per indicare ogni tipo di riquadro.

I caratteri del riquadro e le loro relazioni input-output sono i seguenti:
( Tè per l'input superiore, Lper l'input sinistro, Rper l'output destro, Bper l'output inferiore).

  1. Zero: 0o (spazio) → R = 0,B = 0
  2. Uno: 1R = 1,B = 1
  3. Croce: +R = L,B = T
  4. Specchio: \R = T,B = L
  5. Solo in alto: UR = T,B = T
  6. Solo a sinistra: )R = L,B = L
  7. Non: !R = not L,B = not T
  8. E: &R = L and T,B = L and T
  9. Oppure: |R = L or T,B = L or T
  10. Xor: ^R = L xor T,B = L xor T

Sfida

Scrivi un programma o una funzione che 0 1+\U)!&|^includa una griglia rettangolare di caratteri che rappresenta un "circuito" realizzato usando le dieci tessere duodadiche basate sulla logica. Devi anche prendere due stringhe di 0'e 1'; uno sarà la colonna di input a sinistra e uno sarà la riga di input in alto. Il programma / funzione deve stampare / restituire la riga di output in basso e la colonna di output a destra (anche in 0'se 1').

Ad esempio, in questa griglia

+++
+++

tutti gli ingressi scorrono direttamente attraverso la griglia verso le uscite

 ABC
D+++D
E+++E
 ABC

quindi un input di 010/ 01avrebbe output 010/ 01:

 010
0+++0
1+++1
 010

L'output esatto del tuo programma sarebbe [bottom output row]\n[right output column]o [bottom output row]/[right output column]:

010
01

o

010/01

Se hai scritto una funzione, potresti restituire le due stringhe in una tupla o in un elenco (o comunque stamparle).

Dettagli

  • Prendi i tre input come stringhe in qualsiasi modo ragionevole (preferibilmente nella griglia dell'ordine, nella riga superiore, nella colonna di sinistra): riga di comando, file di testo, sdtin, funzione arg.
  • Puoi presumere che le lunghezze delle righe e delle colonne di input corrispondano alle dimensioni della griglia e conterranno solo 0"e 1".
  • La griglia deve utilizzare i caratteri appropriati ( 0 1+\U)!&|^). Ricordalo 0e intendi la stessa cosa.

Casi test

(Leggi I / O come top/ leftbottom/ right.)

Nand:

&!

00/ 001/ 1
00/ 101/ 1
10/ 001/ 1
10/ 111/0

Tutti quelli:

1111
1\+\
1+\+
1\+\

Qualsiasi input dovrebbe risultare in 1111/ 1111.

Xor di Nand: (nota la colonna degli spazi finali)

\)+\ 
U&!& 
+! ! 
\&!& 
   ! 

00000/ 0000000000/ 00000
00000/ 1000000010/ 00000
10000/ 0000000010/ 00000
10000/ 1000000000/00000

Zig zag:

+++\00000000
000\!!!!\000
00000000\+++

Il primo bit dell'ingresso sinistro diventa l'ultimo bit dell'uscita destra. Tutto il resto è 0.

000000000000/ 000000000000000/ 000
000000000000/ 100000000000000/001

Propagazione:

)))
UUU
U+U
U+U
UUU

Il primo bit dell'ingresso sinistro va a tutte le uscite.

000/ 00000000/ 00000
000/ 10000111/11111

Ecco un esempio di tutti i casi di test della griglia 1 × 1.

punteggio

Vince l' invio più breve in byte .

Bonus: quali "circuiti" fantastici puoi realizzare?

PS Non preoccuparti di googling "tessere duodadiche". Li ho inventati ieri; D
Se vuoi discutere di espandere questa idea in un linguaggio di programmazione completo, vieni in questa chat .


11
+1 per una bella sfida, ma anche perché hai inventato le tessere duodyadic, che è DAVVERO bello.
Alex A.

3
+1 È davvero del tutto inutile google questo: goo.gl/zuqfdW . Bella sfida!
BrainSteel

Sono con loro Sono molto più interessato alle tue tessere come linguaggio di programmazione che a questa particolare sfida di golf. PS: ci sono 16 possibili tessere, quindi trovare lettere / nomi per gli altri sei sarebbe pulito.
Sparr,

Sarebbe interessante avere blocchi che emettono / immettono da direzioni diverse, perché altrimenti non è possibile effettuare un latch poiché tutto scorre in una direzione verso il basso.
Sp3000,

2
Potresti cambiare T / B in U (p) / D (proprio), in modo da poter avere F / B in modo analogo alla notazione del cubo di Rubik, e poi. . . cubi tritriadici?
Soham Chowdhury,

Risposte:


8

Pyth, 122

Tipo di mostro. Utilizza semplicemente la ricorsione, niente di speciale come la programmazione dinamica.

D:NGHR@Cm+d[1HG&GH|GHxGH0),[GH!G)[HG!H)x"+\\!1U)&|^"N#aYw)M:@@YGH?hgGtHHv@eYG?egtGHGv@ePYHjkm+0egtleYklePYjkm+0hgbtlePYleY

Dimostrazione online .

L'input è nel seguente modo: prima la griglia (senza escape, senza simboli extra) e poi le due linee di input, ad es. (Zig zag)

+++\00000000
000\!!!!\000
00000000\+++
000000000000
100

8

Mathematica, 331 276 270 267 264 262 252 250 byte

Print@@@{#[[2;;,-1,2]],#[[-1,2;;,1]]}&@MapIndexed[h=Characters;({r@#2,b@#2}=<|##|>&@@Thread[h@"0 1+\\)U!&|^"->{0,0,1,i={##},{#2,#},##,1-i,1##,Max@i,(#-#2)^2}]&[r[#2-{1,0}],b[#2-{0,1}]]@#{1,1})&,Join[h@{"0"<>#3},h@StringSplit[#2<>"
"<>#,"
"]],{2}]&

Il è un carattere Unicode, ad uso privato, che Mathematica utilizza come apice T, cioè è l'operatore di trasposizione.

Ecco una versione più leggibile:

Print @@@ {#[[2 ;;, -1, 2]], #[[-1, 2 ;;, 1]]} &@
  MapIndexed[h = Characters;
   (
     {r@#2, b@#2} = <|##|> & @@ Thread[
            h@"0 1+\\)U!&|^" -> {
              0,
              0,
              1,
              i = {##},
              {#2, #},
              ##,
              1 - i,
              1 ##,
              Max@i,
              (# - #2)^2
              }] & [
          r[#2 - {1, 0}],
          b[#2 - {0, 1}]
          ] @ # {1, 1}
     ) &,
   Join[
    h@{"0" <> #3},
    h@StringSplit[#2 <> "\n" <> #, "\n"]\[Transpose]
   ],
   {2}] &

Questa è una funzione senza nome che accetta le tre stringhe per gli input griglia, superiore e sinistro e stampa gli output inferiore e destro.

Spiegazione

Esaminiamo questo passo per passo (cercherò di non assumere alcuna conoscenza di Mathematica). Hai bisogno di leggere il codice di nuovo in primo piano. L'algoritmo di base passa attraverso le linee che calcolano ciascuna funzione e memorizzano i risultati fa cui accedono i riquadri successivi.

Elaborazione dell'input

Questo è questo bit:

Join[
  h@{"0" <> #3},
  h@StringSplit[#2 <> "\n" <> #, "\n"]\[Transpose]
]

Questo semplicemente divide la griglia in un elenco nidificato di caratteri (nota che ho definito hcome alias per Characterqualche parte del codice) e quindi antepone una riga e una colonna con gli input. Questo funziona, perché 1e 0sono anche i nomi dei riquadri a funzione costante, quindi effettivamente metterli sullo ha lo stesso effetto di inserire manualmente gli input. Poiché si tratta di funzioni, tecnicamente prenderanno il loro input dall'esterno della griglia, ma poiché sono funzioni costanti che non contano. L'angolo in alto a sinistra ottiene un 0ma questo è abbastanza arbitrario poiché i risultati di quella tessera non vengono mai usati.

Nota anche la trasposizione. L'aggiunta di colonne richiede più caratteri rispetto all'aggiunta di righe, quindi traspongo la griglia dopo aver aggiunto la riga superiore. Ciò significa che in alto / in basso e a sinistra / a destra vengono scambiati per la parte principale del programma, ma sono completamente intercambiabili, quindi non importa. Devo solo assicurarmi di restituire i risultati nell'ordine corretto.

Risolvere la griglia

(Questa sezione è leggermente obsoleta. Risolverà una volta che sono davvero sicuro di aver finito di giocare a golf.)

Successivamente, passiamo MapIndexedal livello interno di questo elenco nidificato. Questo chiama la funzione anonima fornita come primo argomento per ciascun personaggio nella griglia, dandogli anche un elenco con le due coordinate correnti. La griglia viene attraversata in ordine, quindi possiamo calcolare in modo sicuro ogni cella in base a quelle precedenti.

Usiamo le variabili r(ight) e b(ottom) come tabelle di ricerca per i risultati di ogni cella. La nostra funzione anonima contiene le coordinate correnti #2, quindi riceviamo gli input da qualsiasi cella

r[#2 - {1, 0}],
b[#2 - {0, 1}]

Si noti che nella prima riga e colonna questo accederà a valori non definiti di re b. Mathematica non ha davvero un problema con questo e ti restituirà semplicemente le tue coordinate, ma scartiamo comunque questo risultato, poiché tutte le tessere in quella riga / colonna sono funzioni costanti.

Ora questa cosa:

<|##|> & @@ Thread[
  h@"0 1+\\U)!&|^" -> {
     z = {0, 0}, z, o = 1 + z, {##}, ...
  }] &

È una forma di golf di

<|"0" -> (z = {0, 0}), " " -> z, "1" -> (o = 1 + z), "+" -> {##}, ... |> &

Che a sua volta è una funzione che, dati i due input del riquadro, restituisce un'Associazione (la chiameresti una hashmap o una tabella in altre lingue), che contiene tutti i possibili risultati del riquadro per questi due input. Per capire come sono implementate tutte le funzioni, è necessario sapere che è possibile accedere al primo argomento di tale funzione #e al secondo con #2. Inoltre, ##fornisce una sequenza di entrambi gli argomenti che possono essere utilizzati per "dividere" gli argomenti.

  • 0: è semplice, restituiamo solo una costante {0, 0}e la assegniamo anche zper un uso futuro (ad es. nel riquadro dello spazio).
  • 1: è essenzialmente giusto {1,1}, ma avere zquesto è abbreviato 1+z. Salviamo anche questo o, perché tornerà utile per tutte le tessere in cui entrambe le uscite sono identiche.
  • +: Qui utilizziamo la sequenza. {##}è uguale {#,#2}e passa entrambi gli input attraverso invariato.
  • \: Ci scambiamo i due argomenti, {#2,#}.
  • U: Ora possiamo farne uso o. o#2significa {1,1}*#2quindi abbiamo semplicemente inserito l'argomento principale in entrambi gli output.
  • ): Analogamente per l'argomento a sinistra: o#.
  • !: Bitwise non è fastidioso in Mathematica, ma dato che hanno sempre e solo 0e 1, si può semplicemente sottrarre due ingressi da 1(invertendo così loro) e trasmetterle: 1-{##}.
  • &: Questo è abbastanza elegante. Per prima cosa notiamo che bit per bit 0ed 1è identico alla moltiplicazione. Inoltre, o##è lo stesso di o*#*#2.
  • |: Ancora una volta, usiamo una funzione equivalente. Bit a bit o è lo stesso Maxdi questo caso, quindi applichiamo Maxgli argomenti di input e moltiplichiamo il risultato in {1,1}.
  • ^: Il più breve che ho trovato per xor è prendere la differenza e quadrarla (per garantire la positività), quindi abbiamo o(#-#2)^2.

Dopo che questa funzione completa e restituisce l'intera associazione, utilizziamo il carattere della cella corrente per estrarre l'elemento a cui siamo interessati e memorizzarlo in re b. Si noti che questo è anche il valore di ritorno della funzione anonima utilizzata in MapIndexed, quindi la mappatura mi darà effettivamente una griglia di tutti i risultati.

Elaborazione dell'output

MapIndexedrestituisce una griglia 3D, in cui la prima dimensione corrisponde alla coordinata della griglia orizzontale (ricordare la trasposizione precedente), la seconda dimensione corrisponde alla coordinata della griglia verticale e la terza indica se abbiamo un output inferiore o sinistro. Si noti che questo contiene anche la riga e la colonna di input che è necessario eliminare. Quindi accediamo all'output inferiore della riga inferiore con

#[[2;;,-1,2]]

e l'output corretto della colonna finale con

#[[-1,2;;,1]]

Si noti che 2;;è un intervallo dal secondo all'ultimo elemento.

Infine, applichiamo Printa entrambi (usando @@@come zucchero sintattico per il secondo livello Apply), che stampa semplicemente tutti i suoi argomenti back-to-back (e poiché è applicato a due espressioni separate, ci sarà una nuova riga tra bottom e uscita corretta).


8

C, 332 309 272 270 266 259 247 225 byte

#define C(x)*c-x?
i,k,T,L,m;f(c,t,l)char*c,*t,*l;{while(L=l[i]){for(k=0;T=t[k];c++)L=C(49)C(43)C(92)C(85)C(41)C(33)C(38)C('|')C(94)T=48:(T^=L-48):(T|=L):(T&=L):(T^=1,L^1):(T=L):T:(m=T,T=L,m):L:(T=49),t[k++]=T;c++;l[i++]=L;}}

Visualizza i risultati online qui!

Questo definisce una funzione void f(char*, char*, char*), che dovrebbe prendere la scheda come primo input, quindi la riga superiore di input e quindi la riga sinistra di input.

Ecco cosa ho usato per testarlo:

#include "stdio.h"
int main() {
    char buf[1024],top[33],left[33];
    /* Copy and paste an example circuit as the first input,
       and put a 'Q' immediately after it. 
       Note that the Q is never touched by the function f, and is used
       solely as a delimiter for input. */
    scanf("%[^Q]Q ",buf);
    /* Then enter your top inputs */
    scanf("%[01]%*[^01]", top);
    /* Then your left ones */
    scanf("%[01]", left);
    /* OUTPUT: Bottom\nRight */
    f(buf, top, left);
    return 0;
}

Pertanto, inserendo il moltiplicatore a 2 bit di Sp3000:

UUUU))))
UU++)))&
UUU+)  U
UU++&))U
U++&+)^U
U)&\&)UU
   U+^UU
   \&UUUQ
11110000
00000000

Noi abbiamo:

00001001
11111111

In un'altra nota, con in mente il mezzo sommatore di Sp3000, mi piacerebbe vedere un sommatore completo ... Uno di voi ragazzi lo ha fatto! Non penso che il sistema si adatti da solo come linguaggio di programmazione, ma è stato molto interessante. Questo sembra comunque un obiettivo eccellente per metagolf!

Una breve spiegazione:

Ecco il codice disfatto, commentato:

/* We define the first half of the ?: conditional operator because, well,
   it appears over and over again. */
#define C(x)*c-x?
/* i,k are counting variables
   T,L are *current* top and left inputs */
i,k,T,L,m;
f(c,t,l)char*c,*t,*l;{
    /* The outer loop iterates from top to bottom over l and c */
    while(L=l[i]){
        /* Inner loop iterates from left to right over t and c */
        for(k=0;T=t[k];c++)
            /* This line looks awful, but it's just a bunch of character
            comparisons, and sets T and L to the output of the current c */
            L=C(49)C(43)C(92)C(85)C(41)C(33)C(38)C('|')C(94)T=48:(T^=L-48):(T|=L):(T&=L):(T^=1,L^1):(T=L):T:(m=T,T=L,m):L:(T=49),
            /* Write our output to our input, it will be used for the next row */
            t[k++]=T;
        c++; /*Absorbs the newline at the end of every row */
        /* Keep track of our right-most outputs, 
        and store them in the handy string passed to the function. */
        l[i++]=L;
    }
    /* Bottom output is now stored entirely in t, as is right output in l */        
}

Esaminiamo c, da sinistra a destra (quindi dall'alto verso il basso), riscrivendo gli tinput ogni volta e spingendo fuori l'output più a destra che viene inserito nella lstringa. Possiamo immaginare questo come sostituzione della fila superiore di ccon 1's e 0' s iterativo, e tenere traccia dei bit che vengono spinti fuori a destra.

Ecco una sequenza più visiva, riga per riga:

 111                                  
1&+^  =>  110 ->0  =>     ->0  =>     0 Thus, "01" has been written to l,
1+&+     1+&+         110 ->1         1
                                  110   And "110" is stored currently in t.

Questo ovviamente diventa più complicato con simboli e dimensioni diverse, ma l'idea centrale vale. Funziona solo perché i dati non scorrono mai verso l'alto o a sinistra.


Un sacco di potenziale per giocare a golf! Inizia modificando l'intestazione di fa f(c,t,l)char*c,*t,*l(non dare un cazzo sul tipo di ritorno).
FUZxxl

@FUZxxl Qualcuno l'ha menzionato in chat, ma non sono riuscito a farlo funzionare. Questo comportamento è standard? LLVM genera almeno 2 errori con quella linea.
BrainSteel

Scusate. Avrei dovuto f(c,t,l)char*c,*t,*l;. Non compilare in modalità C11, poiché la regola int implicita che ci consente di eliminare il tipo restituito è stata eliminata in quella revisione.
FUZxxl

@FUZxxl Sembra fallire anche in C99. In effetti, ogni modalità in cui ho impostato il compilatore ha rifiutato quel codice.
BrainSteel

Hai aggiunto il punto e virgola subito dopo *l? Si compila in modalità C99 sulla mia macchina.
FUZxxl

7

Python 2, 316 byte

Questa funzione crea 10 funzioni lambda di tile, quindi scorre la griglia, aggiornando gli stati logici. Vengono quindi stampati gli stati logici finali verticali e orizzontali.

def b(d,j,g):
 h=enumerate;e=dict((s[0],eval('lambda T,L:('+s[1:]+')'))for s in' 0,0#00,0#11,1#+L,T#\\T,L#UT,T#)L,L#!1-L,1-T#&T&L,T&L#|T|L,T|L#^T^L,T^L'.split('#'));j=list(j+'\n');g=list(g)
 for y,k in h(d.split('\n')):
  L=g[y]
  for x,c in h(k):T=j[x];L,B=e[c](int(T),int(L));j[x]=`B`
  g[y]=`L`
 print''.join(j+g)

Il codice non golfato incluso i test:

def logic(grid, top, left):
    loop = enumerate;
    func = dict((s[0], eval('lambda T,L:('+s[1:]+')')) for s in ' 0,0#00,0#11,1#+L,T#\\T,L#UT,T#)L,L#!1-L,1-T#&T&L,T&L#|T|L,T|L#^T^L,T^L'.split('#'));
    top = list(top+'\n');
    left = list(left)
    for y,row in loop(grid.split('\n')):
        L = left[y]
        for x,cell in loop(row) :
            T = top[x];
            L, B = func[cell](int(T), int(L));
            top[x] = `B`
        left[y] = `L`
    print ''.join(top + left)

import re
testset = open('test.txt', 'rt').read().strip()
for test in testset.split('\n\n'):
    if test.endswith(':'):
        print '------------------\n'+test
    elif re.match('^[01/\n]+$', test, re.S):
        for run in test.split():
            top, left = run.split('/')
            print 'test', top, left
            logic(grid, top, left)
    else:
        grid = test

Il test.txtfile (inclusi altri 2 test di Sp3000):

Nand:

&!

00/0
00/1
10/0
10/1

All ones:

1111
1\+\
1+\+
1\+\

1001/1100

Xor from Nand (note the column of trailing spaces):

\)+\ 
U&!& 
+! ! 
\&!& 
   ! 

00000/00000
00000/10000
10000/00000
10000/10000

Half adder:

+))
U&+
U+^

000/000
000/100
100/000
100/100

Right shift:

\\\
\++
\++

001/110
010/101
101/100

L'output del test:

------------------
Nand:
test 00 0
01
1
test 00 1
01
1
test 10 0
01
1
test 10 1
11
0
------------------
All ones:
test 1001 1100
1111
1111
------------------
Xor from Nand (note the column of trailing spaces):
test 00000 00000
00000
00000
test 00000 10000
00010
00000
test 10000 00000
00010
00000
test 10000 10000
00000
00000
------------------
Half adder:
test 000 000
000
000
test 000 100
001
101
test 100 000
101
001
test 100 100
110
110
------------------
Right shift:
test 001 110
000
111
test 010 101
101
010
test 101 100
010
110

7

Python 2, 384 338 325 byte

def f(G,T,L):
 def g(x,y):
  if x>-1<y:l=g(x-1,y)[1];t=g(x,y-1)[0];r=l,t,1-l,0,0,1,t,l,l&t,l|t,l^t;i="+\\!0 1U)&|^".index(G[y*-~W+x]);return((t,l,1-t)+r[3:])[i],r[i]
  return(int((y<0)*T[x]or L[y]),)*2
 H=G.count("\n")+1;W=len(G)/H;return eval('"".join(map(str,[g(%s]for _ in range(%s)])),'*2%('_,H-1)[0','W','W-1,_)[1','H'))

Seriamente CH, se questo non è già un giocattolo dovresti iniziare a chiamare alcune fabbriche di giocattoli.

Più golfista e molto meno efficiente ora, ma non ho ancora raggiunto CarpetPython. Input come f("1111\n1\\+\\\n1+\\+\n1\\+\\","0101","1010"), output è una tupla di due stringhe. Assicurati che la scheda non abbia una nuova riga finale, che romperà le cose.

Programma di test

def f(G,T,L):
 def g(x,y):
  if x>-1<y:l=g(x-1,y)[1];t=g(x,y-1)[0];r=l,t,1-l,0,0,1,t,l,l&t,l|t,l^t;i="+\\!0 1U)&|^".index(G[y*-~W+x]);return((t,l,1-t)+r[3:])[i],r[i]
  return(int((y<0)*T[x]or L[y]),)*2
 H=G.count("\n")+1;W=len(G)/H;return eval('"".join(map(str,[g(%s]for _ in range(%s)])),'*2%('_,H-1)[0','W','W-1,_)[1','H'))


import itertools

G = r"""
+))
U&+
U+^
""".strip("\n")

def test(T, L):
    print f(G, T, L)

def test_all():
    W = len(G[0])
    H = len(G)

    for T in itertools.product([0, 1], repeat=len(G.split("\n")[0])):
        T = "".join(map(str, T))

        for L in itertools.product([0, 1], repeat=len(G.split("\n"))):
            L = "".join(map(str, L))

            print "[T = %s; L = %s]" % (T, L)
            test(T, L)
            print ""

test("000", "000")
test("000", "100")
test("100", "000")
test("100", "100")

Puoi anche testare tutti i possibili casi con test_all().

Casi di prova extra

Mezzo sommatore

Ecco un mezzo sommatore che aggiunge i bit in alto a sinistra, producendo <input bit> <carry> <sum>:

+))
U&+
U+^

test:

000 / 000  ->  000 / 000
000 / 100  ->  001 / 101
100 / 000  ->  101 / 001
100 / 100  ->  110 / 110

L'uscita dovrebbe essere la stessa anche se il secondo / terzo bit degli ingressi viene modificato.

Spostamento a destra

Dato abc / def, questo produce fab / cde:

\\\
\++
\++

test:

001 / 110 -> 000 / 111
010 / 101 -> 101 / 010
101 / 100 -> 010 / 110

Selezionatore a 3 bit

Ordina i primi tre bit della parte superiore negli ultimi tre bit della parte inferiore. L'output corretto è spazzatura.

UUU)))
UU)U U
U&UU U
U+|&)U
\UU++|
 \)&UU
  \+|U
   UUU

test:

000000 / 00000000 -> 000000 / 00000000
001000 / 00000000 -> 000001 / 11111111
010000 / 00000000 -> 000001 / 00001111
011000 / 00000000 -> 000011 / 11111111
100000 / 00000000 -> 000001 / 00001111
101000 / 00000000 -> 000011 / 11111111
110000 / 00000000 -> 000011 / 00001111
111000 / 00000000 -> 000111 / 11111111

Moltiplicatore a 2 bit per 2 bit

Prende il 1 ° / 2 ° bit della parte superiore come primo numero e il 3 ° / 4 ° bit della parte superiore come secondo numero. Emette gli ultimi quattro bit di bottom. L'output corretto è spazzatura.

UUUU))))
UU++)))&
UUU+)  U
UU++&))U
U++&+)^U
U)&\&)UU
   U+^UU
   \&UUU

Modifica: golfato una colonna e due righe.

test:

00000000 / 00000000 -> 00000000 / 00000000
00010000 / 00000000 -> 00000000 / 10000000
00100000 / 00000000 -> 00000000 / 00000000
00110000 / 00000000 -> 00000000 / 10000000
01000000 / 00000000 -> 00000000 / 00000000
01010000 / 00000000 -> 00000001 / 11111111
01100000 / 00000000 -> 00000010 / 00000000
01110000 / 00000000 -> 00000011 / 11111111
10000000 / 00000000 -> 00000000 / 00000000
10010000 / 00000000 -> 00000010 / 10000000
10100000 / 00000000 -> 00000100 / 00000000
10110000 / 00000000 -> 00000110 / 10000000
11000000 / 00000000 -> 00000000 / 00000000
11010000 / 00000000 -> 00000011 / 11111111
11100000 / 00000000 -> 00000110 / 00000000
11110000 / 00000000 -> 00001001 / 11111111

1

R, 524 517

Probabilmente un sacco di spazio per ridurlo al momento, ma questo è stato davvero interessante da fare. Ci sono due funzioni. La funzione d è il lavoratore e f è il comparatore.

La funzione d è chiamata con 3 stringhe, Gates, Top e Left. I cancelli sono inseriti in una matrice determinata dalla larghezza.

I=strtoi;S=strsplit;m=matrix;f=function(L,T,G){O=I(c(0,1,L,T,!L,!T,L&T,L|T,xor(L,T)));X=which(S(' 01+\\U)!&|^','')[[1]]==G);M=m(c(1,1,1,2,1,1,3,2,2,4,3,4,5,4,3,6,4,4,7,3,3,8,5,6,9,7,7,10,8,8,11,9,9),nrow=3);return(c(O[M[2,X]],O[M[3,X]]))};d=function(G,U,L){W=nchar(U);H=nchar(L);U=c(list(I(S(U,'')[[1]])),rep(NA,H));L=c(list(I(S(L,'')[[1]])),rep(NA,W));G=m((S(G,'')[[1]]),nrow=W);for(i in 1:H)for(n in 1:W){X=f(L[[n]][i],U[[i]][n],G[n,i]);L[[n+1]][i]=X[1];U[[i+1]][n]=X[2]};cat(U[[H+1]],' / ',L[[W+1]],sep='',fill=T)}

Un po 'formattato

I=strtoi;S=strsplit;m=matrix;
f=function(L,T,G){
    O=I(c(0,1,L,T,!L,!T,L&T,L|T,xor(L,T)));
    X=which(S(' 01+\\U)!&|^','')[[1]]==G);
    M=m(c(1,1,1,2,1,1,3,2,2,4,3,4,5,4,3,6,4,4,7,3,3,8,5,6,9,7,7,10,8,8,11,9,9),nrow=3);
    return(c(O[M[2,X]],O[M[3,X]]))
};
d=function(G,U,L){
    W=nchar(U);H=nchar(L);
    U=c(list(I(S(U,'')[[1]])),rep(NA,H));
    L=c(list(I(S(L,'')[[1]])),rep(NA,W));
    G=m((S(G,'')[[1]]),nrow=W);
    for(i in 1:H)
        for(n in 1:W){
            X=f(L[[n]][i],U[[i]][n],G[n,i]);
            L[[n+1]][i]=X[1];
            U[[i+1]][n]=X[2]
        };
    cat(U[[H+1]],' / ',L[[W+1]],sep='',fill=T)
}

Alcuni test

> d('&!','00','0')
01 / 1
> d('&!','00','1')
01 / 1
> d('&!','10','0')
01 / 1
> d('&!','10','1')
11 / 0
> d('\\)+\\ U&!& +! ! \\&!&    ! ','00000','00000')
00000 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','00000','10000')
00010 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','10000','00000')
00010 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','10000','10000')
00000 / 00000
> d('+++\\00000000000\\!!!!\\00000000000\\+++','000000000000','100')
000000000000 / 001
> d('+++\\00000000000\\!!!!\\00000000000\\+++','000000000000','000')
000000000000 / 000
> d('+))U&+U+^','000','000')
000 / 000
> d('+))U&+U+^','000','100')
001 / 101
> d('+))U&+U+^','100','000')
101 / 001
> d('+))U&+U+^','100','100')
110 / 110
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.