Programowanie za pomocą bitów i bajtów

40

W tym wyzwaniu napiszesz tłumacza prostego języka, który wymyśliłem. Język oparty jest na pojedynczym akumulatorze A, który ma dokładnie jeden bajt długości. Na początku programu A = 0. Oto instrukcje dotyczące języków:

!: Inwersja

Ta instrukcja po prostu odwraca każdy kawałek akumulatora. Każde zero staje się jednością, a każdy staje się zerem. Prosty!

>: Shift Right

Ta instrukcja przesuwa się co chwilę w jednym miejscu w prawo. Najbardziej lewy bit staje się zerem, a skrajny prawy bit jest odrzucany.

<: Przesuń w lewo

Ta instrukcja przesuwa się co chwilę w jednym miejscu w lewo. Najbardziej wysunięty w prawo bit staje się zerem, a najbardziej wysunięty w lewo bit jest odrzucany.

@: Zamień Nybbles

Ta instrukcja zamienia cztery górne bity A na cztery dolne bity. Na przykład, jeśli A jest 01101010i wykonasz @, A będzie 10100110:

 ____________________
 |                  |
0110 1010    1010 0110
      |_______|

To wszystkie instrukcje! Proste, prawda?

Zasady

  • Twój program musi zaakceptować wejście raz na początku. To będzie linia kodu. To nie jest interaktywny tłumacz! Możesz zaakceptować dane wejściowe tylko raz i nie musisz zapętlać z powrotem do początku po wykonaniu tej linii.
  • Twój program musi ocenić wspomniane dane wejściowe. Każda postać, która nie jest wymieniona powyżej, jest ignorowana.
  • Twój program powinien następnie wydrukować ostateczną wartość akumulatora w systemie dziesiętnym.
  • Obowiązują zwykłe zasady dotyczące prawidłowych języków programowania.
  • Standardowe luki są niedozwolone.
  • To jest , wygrywa najmniejsza liczba bajtów.

Oto kilka małych programów do testowania swoich zgłoszeń. Przed strzałką jest kod, po nim oczekiwany wynik:

  • ! -> 255
  • !>> -> 63
  • !<@ -> 239
  • !nop!&6*! -> 255

Cieszyć się!

bitsnbites
źródło
Zakładam ! -> 255, że wykorzystamy tutaj 8 bitów na bajt? Pytanie nie jest jednoznaczne.
Toby Speight
3
@TobySpeight Bajt z definicji ma 8 bitów.
HyperNeutrino,

Odpowiedzi:

15

Pyth, 36 35 bajtów

u%@[t_G/G2yGi_jGJ16JG)x"!><@"H256z0

Uprząż testowa

Wewnętrzna reprezentacja akumulatora jest liczbą całkowitą. Ta liczba całkowita jest modyfikowana przez 256 przy każdej iteracji, zgodnie z potrzebami. Operacje wykonane są -G-1, G/2, G*2i Gprzekształca się w podstawie 16, odwróconej i przekształcany z powrotem do podstawy 10, gdy Gjest w akumulatorze.

Przegapiłem zdanie o ignorowaniu wszystkiego innego. Zostało to naprawione. Dzięki, @Dennis.

isaacg
źródło
Więc -G-1jest krótszy niż ~Gw Pyth? Wątpię w to.
CalculatorFeline
Kod t_G, o którym mowa, jest w rzeczywistości , gdzie _jest negacja i tjest -1. W Pyth ~oznacza coś zupełnie innego.
isaacg
Miałem na myśli Python ~(bitowe NIE)
CalculatorFeline
@CalculatorFeline Chodzi mi o to, że w Pyth nie ma funkcji 1-znakowej z takim efektem, więc powyższy kod (przynajmniej dla tej operacji) jest tak dobry, jak to tylko możliwe.
isaacg
13

C, 96

Zakładając wejście ASCII (lub zgodne):

a;main(c){while(c=getchar()+1)a=(c^34?c^61?c^63?c^65?a:a*257/16:a/2:a*2:~a)&255;printf("%u",a);}

Tidier:

a;
main(c){
  while(c=getchar()+1)
    a=(c^34?
      c^61?
        c^63?
          c^65?
            a
          :
            a*257/16
        :
          a/2
      :a*2:~a
    )&255;
  printf("%u",a);
}

Zasadniczo jest to tylko kolekcja zagnieżdżonych wyrażeń trójskładnikowych. Zwiększam wartość uzyskaną z, getchar()aby EOF (-1) dawał wartość zero i program kończy działanie.

(link ideone)

piskliwy kostuch
źródło
1
Sam spróbowałem tego wyzwania i napisałem prawie dokładnie ten sam kod. Btw. twój program nie upuszcza bitu podczas przesuwania w górę (wejście: !<>powinno skutkować 127i nie 255). Zdefiniuj swoją ajako charlub użyj linii a&=255(i użyj %u), aby uzyskać właściwy efekt. Ponadto można skrócić swoją negację a^255do ~a. a>>4&15jest również krótszy niż twój (a&240)/16.
MarcDefiant
Ach, dobra racja. Okazuje się, że skuteczniej było maskować dolne 8 bitów przy każdej iteracji.
piskliwy ossifrage
1
W takim przypadku możesz nawet użyć ciągu formatu %uzamiast%hhu
MarcDefiant
1
Właśnie to widziałem, ale możesz też użyć a/16|a*16zamiast a/16|(a&15)*16. Kilka bitów na górze jest usuwanych przez &255.
MarcDefiant
1
Drobne ulepszenie: a*257/16jest o jeden bajt krótsze niż a/16|a*16.
Toby Speight
11

Python 3, 133 bajty

Używa słownika, aby uzupełnić brak składni z przełączaniem wielkości liter w Pythonie. Zobacz więcej tutaj .

a="0"*8
for i in input():a={"!":''.join(str(1-int(b))for b in a),"<":a[1:]+"0",">":"0"+a[:-1],"@":a[4:]+a[:4]}.get(i,a)
print(int(a,2))

Akumulator to ciąg, który na końcu jest przekształcany w podstawową liczbę 10.

Przykład I / O:

$ python3 bitsnbytes.py
!
255
$ python3 bitsnbytes.py
!>>
63
$ python3 bitsnbytes.py
!<@
239
$ python3 bitsnbytes.py
!nop!&6*!
255
Rozpad beta
źródło
Gdyby to był prawdziwy, interaktywny tłumacz, byłby for i in sys.stdin::)
Zizouz212,
4
@ Zizouz212 Wierzę, że masz na myśli, jeśli był interaktywny; dla mnie wygląda to na prawdziwego tłumacza. ;)
Alex A.
9

JavaScript (ES6), 80 91 90 bajtów

a=>[...a].reduce((p,c)=>c=='!'?p^255:c=='<'?p*2%256:c=='>'?p>>1:c=='@'?p/16|0+p%16*16:p,0)

Prawie tak krótko, jak to możliwe. Definiuje anonimową funkcję, która przyjmuje program jako dane wejściowe.

  • Dla !bierze x XOR 255, jak JS na ~uznałby xliczbę 32-bitową.
  • W przypadku <, mnoży się xprzez 2 i wykorzystuje wynik mod 256.
  • Bo >naprawdę przesuwa bity x1-bitowe w prawo.
  • Dla @, podłogi x/16i dodaje to x%16*16.

Dzięki @vihan za sugestię użycia reducedo zapisania bajtu.

ETHprodukcje
źródło
Możesz użyć, <aby zaoszczędzić około 4 bajtów. Użycie funkcji zmniejszania może również zaoszczędzić niektóre bajty
Downgoat
1
@vihan Czy masz na myśli <zamiast ==? Jeśli tak, to nie zadziałałoby, ponieważ postacie no-op nieprawidłowo wykonałyby operację. Użyłem tego w moim poprzednim 80-bajtowym rozwiązaniu.
ETHprodukcje
Czy nie jest standardową strzałą tłuszczu ES6 w PPCG, którą musisz zdefiniować?
MayorMonty,
@SpeedyNinja Nie znam żadnego takiego standardu, ale jeśli możesz skierować mnie do posta na temat jednego, zmodyfikuję moją odpowiedź.
ETHprodukcje
8

CJam, 37 bajtów

0q{"!><@"#"~ 2/ 2* GmdG*+ "S/=~255&}/

Wypróbuj online w interpretatorze CJam .

Jak to działa

0                   e# Push 0 (accumulator).
q                   e# Read from STDIN.
{                   e# For each character in the input:
  "!><@"#           e#   Find its index in "!><@" (-1 if not found).
  "~ 2/ 2* GmdG*+ " e#   Push that string.
  S/                e#   Split at spaces to push ["~" "2/" "2*" "GmdG*+" ""].
                    e#     "~"      : signed 64-bit bitwise NOT
                    e#     "2/"     : divide by 2
                    e#     "2*"     : multiply by 2
                    e#     "GmdG*+" : (x) -> (x/16) (x%16) -> (16(x%16) + (x/16))
                    e#     ""       : NOOP
  =~                e#  Select the corresponding string and evaluate it.
  255&              e#  Zero all but the 8 least significant bits.
}/                  e#
Dennis
źródło
8

Java (8), 514 483 411 366 359 239 224 229 198 194 187 186 184 182 181 180 177 znaków

Wow, to było dużo gry w golfa! Dziękujemy wszystkim, którzy dali mi sugestie! Bardzo to doceniam!

interface T{static void main(String[]g)throws Exception{int i,a=0;while((i=System.in.read())!=10)a=(i==33?255-a:i==62?a/2:i==60?a*2:i==64?a>>4|a<<4:a)%256;System.out.print(a);}}

Grał w golfa 31 (!) Bajtów, optymalizując zamianę skórek za pomocą operacji bitowych w przeciwieństwie do długich Integer.???metod.

Grał w golfa 72 znaki (!!!!), usuwając niepotrzebny ciąg znaków utworzony w celu zamiany skubków. Znacznie lepiej niż wcześniej !?

Zagrano 45 znaków (!!) w golfa, usuwając użycie java.util.Scanneri czytanie System.inbezpośrednio. Zauważ, że teraz, gdy minęło wyrażenie lambda, Java 8 nie jest już wymagana! Wystarczy Java 1!

Grał w golfa 7 znaków, tworząc klasę (default)(usunięte publicsłowo kluczowe), dzięki @bmarks

Grał w golfa 120 znaków (!!!!!!!), odwracając wszystkie te długie Integeroperacje klasowe 255 - a. Teraz jest o wiele krótszy!

Gra w golfa 15 (!) Znaków, konwertując zmiany na mnożenie i dzielenie, usuwając nawiasy klamrowe z instrukcji while i austawiając lokalnie w ramach mainmetody.

Ungolfed 9 = (znaki z powodu problemu z przesunięciem w lewo, który nie odrzuca najbardziej wysuniętego w lewo bajtu. Dlatego robię to mod (256). Prawe przesunięcie sprawi, że wynikowa liczba będzie nieco krótsza niż wcześniej, więc nie ma potrzeby używania modna prawym przesunięciu. Moja zamiana skubania zamieni ostatnie 4 bity i skrobanie drugiego do ostatniego, a and (&)obcina wszystkie inne bity. Mój program inwersji nie powoduje żadnych problemów, jeśli pierwotna liczba jest mniejsza niż 256.

Grał w golfa 31 35 znaków dzięki @Geobits poprzez konwersję switchinstrukcji na wiele instrukcji trójkowych , a także konwersję znaków na int, skracając literały.

Grał w golfa 7 znaków, usuwając niepotrzebne &240w zamianie skórek ( (a&240)>>4do a>>4i konwertując (a&15)<<4na a<<4&240. Ostatnia zmiana zagrała tylko jedną postać.

Golfed 1 char przez wyeliminowanie =in a /= 2, ponieważ a = a /= 2jest równoważna a = a / 2.

Zagrał w golfa 2 znaki, zwracając się printlndo print.

Golfed 2 znaków poprzez usunięcie Postępowanie w przypadku a=w a=255-a( a=a=255-aodpowiada a=255-a)

Grał w golfa 1 char, zmieniając się a<<4&240w a%16<<4.

Zagrał w golfa 1 znak, dodając nawiasy na zewnątrz instrukcji trójkowej i wykonując %256. W ten sposób %16zbędne jest w części zamiany skubków z przesunięciem w lewo. Nawiasy dodają 2 znaki, a %16zapisuje 3 znaki.

Golfed 3 znaki zmieniając classsię interfacei usuwanie publicza pomocą funkcji interfejsu metoda statyczna Java 8 za. Dzięki @TheNumberOne (bez komentarza, ale znajdź odpowiedź na „Wskazówki dotyczące gry w golfa w Javie”

HyperNeutrino
źródło
Nie sądzę, żeby klasa była publiczna. Myślę też, że jeśli utworzysz liczbę całkowitą zamiast liczby całkowitej, możesz wykonać a.parseInt, a.toString itp. Zamiast Integer.parseInt, Integer.toString itp.
zaznacza
Dzięki za pierwszą sugestię; Zamierzam jednak usunąć wszystkie Integermetody klasowe.
HyperNeutrino
Być może możesz zrobić while ((i = System.in.read ())> 10) zamiast! = 10, aby zapisać bajt?
zaznacza
Dobry pomysł, ale wtedy wszystko poniżej 10 spowoduje zakończenie programu, a ja mam zignorować inne znaki, a nie koniec świata (a przynajmniej mój program :)) Zastanowię się jednak; być może nie ma prawidłowych znaków ascii poniżej 10.
HyperNeutrino
4
To prawie nigdy nie warto używać switchpodczas golfa. case/ breakSą po prostu zbyt długo. Powinieneś być w stanie uratować grupę, czyniąc całość potrójną; coś w stylua=i=='!'?255-a:i==62?a/2:i=='<'?a*2%256:i=='@'?(a&240)>>4|(a&15)<<4:a;
Geobits
7

Rdza, 121 115 bajtów

fn r(s:&str)->u8{let mut n=0u8;for t in s.chars(){match t{'!'=>n=!n,'>'=>n/=2,'<'=>n<<=1,'@'=>n=n>>4|n<<4,_=>()}}n}

Przykładowy przebieg:

fn main() {
    println!("{}", r("!"));    //=> 255
    println!("{}", r("!>>"));  //=> 63
    println!("{}", r("!<@"));  //=> 239
}

Nie golfowany:

fn run_ungolfed(s: &str) -> u8 {
    let mut n = 0u8;
    for t in s.chars() {
        match t {
            '!' => n = !n,
            '>' => n >>= 1,
            '<' => n <<= 1,
            '@' => n = (n >> 4) | (n & 15) << 4,
            _ => ()
        }
    }
    n
}

Zaskakująco skrót od Rust. Nic innego naprawdę interesującego poza faktem, że nauczyłem się dzisiaj więcej zasad pierwszeństwa - kto wiedział, że (a>>b)|cto to samo, co a>>b|c?

Ogolono bajt, zmieniając n>>=1na n/=2; tego samego nie można jednak zrobić z mnożeniem, ponieważ przepełnienie arytmetyczne jest paniką (tj. awarią) w Rust.

Klamka
źródło
2
Rzecz pierwszeństwo ma sens, gdy się przekonać, że >>to rodzaj jakby podziału i |jest rodzaj jakby dodatkowo.
Lynn,
6

HP 41C / CV / CX (bajty, 42 kroki)

Wyłącznie dla chichotów, tutaj jest dla kalkulatora HP 41C / CV / CX. (Wymaga modułu Rozszerzonych funkcji lub 41CX dla funkcji ATOX.) Niestety kalkulator nie zgłasza rozmiarów programów w bajtach.

Umieść swój program w rejestrze Alpha, co jest trochę trudne, ponieważ nie ma możliwości, aby wejść! lub @ bezpośrednio z klawiatury (aby dołączyć, użyj XTOA z kodami ASCII 33 i 64).

Kroki 08 i 10 pozwalają na ignorowanie niepoprawnych kodów; usuń je, aby zapisać 2 kroki, ale program ulegnie awarii przy nieprawidłowym wprowadzeniu.

01 LBL"BB
02 0
03 LBL A
04 ATOX
05 X=0?
06 GTO E
07 X<>Y
08 SF 25
09 XEQ IND Y
10 CF 25
11 GTO A
12 LBL 33
13 255
14 X<>Y
15 -
16 RTN
17 LBL 60
18 2
19 *
20 256
21 MOD
22 RTN
23 LBL 62
24 2
25 /
26 INT
27 RTN
28 LBL 64
29 RCL X
30 16
31 /
32 INT
33 X<>Y
34 16
35 *
36 256
37 MOD
38 +
39 RTN
40 LBL E
41 RDN
42 RTN
db2
źródło
6

Python 2, 79 bajtów

Uświadomiłem sobie, że zrobiłem wcześniej coś bardzo podobnego do tego w Pythonie. To tylko część mojej odpowiedzi Ruby , ale nawiasem mówiąc, jest to najkrótsza jak na razie odpowiedź w języku Python: D

a=0
for i in raw_input():a=[~a,a/2,a*2,a*16+a/16,a]["!><@".find(i)]&255
print a

Różnica w stosunku do wersji Ruby polega na tym, że ta nie ignoruje niepoprawnych instrukcji podczas iteracji po danych wejściowych. Zamiast tego korzystam z faktu, że Python ma tendencję do zwracania -1zamiast nilgdy nie ma dopasowania - bieżąca wartość ajest dołączana z tyłu tablicy wyników, dzięki czemu wszystkie niepoprawne instrukcje są odwzorowane na tę samą niezmienioną wartość.

daniero
źródło
4

Python 3, 124 94 93 bajty

a=0
for i in input():
 if i in"!><@":a=(i=='!')*(255-a)+(i==">")*a//2+(i=="<")*(a+a)%256+(i=="@")*(16*(a%16)+a//16)
print(a)

„!” jest takie samo jak odejmowanie od 255.
„<” to to samo, co mnożenie przez 2. Ale 8-bitowy rejestr oznacza mod 256.
„>” oznacza dzielenie liczb całkowitych przez 2.
„@” oznacza przesunięcie ostatnich 4 bitów ( a%16) o 4 bity ( *16) i dodanie pierwszych czterech bitów ( a/16).

EDYCJA (czytaj bezwstydne kopiowanie)
Zobaczyłem drugą odpowiedź w pythonie (przez rozpad Beta). Wykorzystuje naprawdę skuteczny sposób symulowania przypadków przełączania za pomocą słownika. Za pomocą tego możemy pisać

a=0
for i in input():a={"!":255-a,"<":a<<1&255,">":a//2,"@":(a%16)<<4+a>>4}.get(i,a)
print(a)

Dzięki, rozpad beta.

Rohcana
źródło
Bez względu na to, jaką operację wykonujesz, musisz zmniejszyć mod, 256prawda? Więc dlaczego nie zrobić na końcu: a={"!":255-a,"<":a*2,">":a//2,"@":(a%16)<<4+a>>4}.get(i,a)%256. To natychmiast oszczędza bajt (bo zrobisz to a*2zamiast a<<1) ... ale odpowiedź @ daniero pokazuje również, że jeśli zrobisz to w ten sposób, (a%16)<<4możesz go skrócić do sprawiedliwego a<<4, ponieważ każdy bit 16 lub większy zostanie wyeliminowany po pomnożeniu o 16 i zmniejsz go mod 256. Fajnie! Ponadto, można teraz zastąpić 255-aprzez -1-a... albo lepiej, po prostu ~a. W sumie te sugestie powinny zaoszczędzić 9 bajtów.
matmandan
3

Haskell, 89 bajtów

a#'!'=255-a
a#'>'=div a 2
a#'<'=mod(a*2)256
a#'@'=mod(a*16)256+div a 16
a#_=a
f=foldl(#)0

Przykład użycia: f "!>>"->63

nimi
źródło
3

Rdza, 111 bajtów

Więcej komentarza do odpowiedzi @ Doorknob, ale nie mam żadnych przedstawicieli do komentarzy, ponieważ właśnie utworzyłem konto.

Można ogolić 10 bajtów z jego rozwiązania w Rust:

fn r(s:&str)->u8{let mut n=0u8;for t in s.chars(){n=match t{'!'=>!n,'>'=>n>>1,'<'=>n<<1,'@'=>n>>4|n<<4,_=>n}}n}
użytkownik4867444
źródło
Pomyślałem, że możemy skrócić się przy użyciu fold ( doc.rust-lang.org/std/iter/trait.Iterator.html#method.fold ), ale zaskakująco wydłuża to czas.
user4867444,
3

Python 3, 127 bajtów

Edycja: zwarcie, dzięki @Jakube

Edycja2: popraw, dziękuję @Anachor

a=0
for i in input():a=(a^255if i=="!"else a>>1if i==">"else a<<1if i=="<"else(a&15)<<4|(a&240)>>4if i=="@"else a)&255
print(a)
uno20001
źródło
Może to dlatego, że nowa linia systemu Windows. To plus dwa bajty. Następnym razem użyję tego licznika bajtów. :-) Dzięki.
uno20001,
Zauważ, że to nie odrzuca skrajnego lewego bitu, gdy lewy się przesuwa, więc !<daje, 510póki powinno być254
Rohcana
Mam nadzieję, że teraz tak jest. Przepraszam za moje błędy, to moje pierwsze wyzwanie w golfa.
uno20001,
3

Cejlon, 297 290

shared void y(){value t=process.readLine()else"";variable Byte a=0.byte;for(c in t){switch(c)case('!'){a=a.not;}case('>'){a=a.rightLogicalShift(1);}case('<'){a=a.leftLogicalShift(1);}case('@'){a=a.and(#f0.byte).rightLogicalShift(4).xor(a.and(#f.byte).leftLogicalShift(4));}else{}}print(a);}

Sformatowany:

shared void y() {
    value t = process.readLine() else "";
    variable Byte a = 0.byte;
    for (c in t) { switch (c)
        case ('!') { a = a.not; }
        case ('>') { a = a.rightLogicalShift(1); }
        case ('<') { a = a.leftLogicalShift(1); }
        case ('@') { a = a.and(#f0.byte).rightLogicalShift(4).xor(a.and(#f.byte).leftLogicalShift(4)); }
        else {} }
    print(a);
}

#fi #f0są liczbami szesnastkowymi dla skubków, .bytekonwertuje liczbę całkowitą na bajt. Mam szczęście, że .stringatrybut Byte'a już używa niepodpisanej reprezentacji bajtu. Na Cejlonie znajduje się również instrukcja switch bez przewijania, a ciąg znaków to lista znaków, które można iterować.

Próbowałem również skrócić nazwy metod długiego przesunięcia za pomocą importu aliasingu, ale tak naprawdę staje się on o 7 bajtów dłuższy:

import ceylon.language{Byte{r=rightLogicalShift,l=leftLogicalShift}}shared void x(){value t=process.readLine()else"";variable Byte a=0.byte;for(c in t){switch(c)case('!'){a=a.not;}case('>'){a=a.r(1);}case('<'){a=a.l(1);}case('@'){a=a.and(#f0.byte).r(4).xor(a.and(#f.byte).l(4));}else{}}print(a);}

Sformatowany:

import ceylon.language {
    Byte {
        r=rightLogicalShift,
        l=leftLogicalShift
    }
}
shared void x() {
    value t = process.readLine() else "";
    variable Byte a = 0.byte;
    for (c in t) {
        switch (c)
        case ('!') { a = a.not; }
        case ('>') { a = a.r(1); }
        case ('<') { a = a.l(1); }
        case ('@') { a = a.and(#f0.byte).r(4).xor(a.and(#f.byte).l(4)); }
        else {}
    }
    print(a);
}

Może to być przydatne, jeśli potrzebujemy tych metod nieco częściej.

Paŭlo Ebermann
źródło
3

Rubin, 81 73 bajty

O wiele prostsze - bez ewaluacji! Dla każdego poprawnego znaku na wejściu ocenia każdą instrukcję i znajduje odpowiednią instrukcję na podstawie indeksu $&(bieżącego znaku na wejściu).

a=0
gets.scan(/[!><@]/){a=[~a,a/2,a*2,a*16+a/16]["!><@".index$&]&255}
p a
daniero
źródło
1
To geniusz. Znacznie krótszy niż w jakikolwiek inny sposób. 2 głosy poparcia przeze mnie!
edc65
Jak podwoić głosowanie ...?
HyperNeutrino
@JamesSmith Prawdopodobnie odnosi się do tego i mojej odpowiedzi na python :)
daniero
@danerio Rozumiem.
HyperNeutrino,
2

STATA, 197 bajtów

di _r(a)
gl b=0
forv x=1/`=length("$a")'{
gl c=substr("$a",`x',1)
if"$c"=="!" gl b=255-$b
if"$c"==">" gl b=int($b/2)
if"$c"=="<" gl b=mod($b*2,256)
if"$c"=="@" gl b=mod($b,16)*16+int($b/16)
}
di $b

Bez golfa

display _request(a) //get the input via prompt and put in var a
global b=0 //initialise A to be 0
forv x=1/`=length("$a")'{ //for loop from 1 to last char in a
global c=substr("$a",`x',1) //get the char at index x in a
if "$c"=="!" global b=255-$b //invert is the same as 255-A
if "$c"==">" global b=int($b/2) //right shift is the same as A/2 (with integer division)
if "$c"=="<" global b=mod($b*2,256) //left shift is the same as A*2%256
if "$c"=="@" global b=mod($b,16)*16+int($b/16) //nibble swap is the same as A%16*16+A/16
}
display $b //display the result of A

Nie działa z tłumaczem online i wymaga niewolnego domyślnego tłumacza. Byłoby to nieco łatwiejsze w przypadku rzeczywistych operacji bitowych, ale nie sądzę, aby były one zbyt przydatne w przypadku większości typowych zastosowań STATA.

znaczniki
źródło
Dlaczego tłumacz online nie działa?
CalculatorFeline
2

JavaScript, 104

[].reduce.call(prompt(),function(a,i){return(i=='!'?~a:i=='>'?a/2:i=='<'?a*2:i=='@'?a>>4|a<<4:a)&255},0)

Zagnieżdżone operatory trójskładnikowe mapują na instrukcje.

BITWISE AND służy do ograniczenia naszego typu Number do jednego bajtu.

Andrew Vermie
źródło
2

Julia, 117 94 86 73 bajtów

p->(a=0x0;[a=c==33?~a:c==60?a<<1:c==62?a>>1:c!=64?a:a<<4|a>>4for c=p];1a)

Jest to anonimowa funkcja, która przyjmuje ciąg znaków i zwraca liczbę całkowitą. Aby go wywołać, przypisz go do zmiennej.

Nie golfowany:

function f(p)
    # Initialize the accumulator to 0 as an 8-bit unsigned integer
    a = 0x0

    # Loop over the characters in the input
    for c in p
        a = c == 33 ? ~ a :        # '!'
            c == 60 ? a << 1 :     # '<'
            c == 62 ? a >> 1 :     # '>'
            c != 64 ? a :          # no-op
            a << 4 | a >> 4        # '@'
    end

    # Convert the accumulator to a regular integer and return
    return Int(a)
end

Zaoszczędzono 8 bajtów dzięki Sp3000 i 13 dzięki Dennis!

Alex A.
źródło
2

JavaScript (ES6), 76 81

Jako funkcja bez nazwy zwraca wartość akumulatora

To przeniesienie super sprytnych odpowiedzi @daniero (które mają zdecydowanie za mało głosów pozytywnych)

Bonus: Państwo może przekazać wartość początkową akumulatorze. Jeśli nie przejdzie, wartość początkowa wynosi 0, jak dla konkretnego.

(p,a)=>(p.replace(/[!<>@]/g,i=>a=(i<'<'?~a:i<'>'?a*2:i<'@'?a/2:a*257/16)&255),a)

Przetestuj poniższy fragment kodu w dowolnej przeglądarce EcmaScript 6 (testowałem w przeglądarce Firefox)

f=(p,a)=>[...p].map(c=>a=255&[a,~a,a*2,a/2,a*257/16][1+'!<>@'.indexOf(c)])|a

// TEST
out=x=>O.innerHTML+=x+'\n'

function go(x) { out(x+' -> '+f(x)) }

go('!'),go('!>>'),go('!<@'),go('!nop!&6*!')

// LESS GOLFED
F=(p,a)=>// a as a parameter, if not passed its value starts as undefined, then becomes NaN, but the operators '&' and '~' treat it as 0
  [...p].map(c => // execute following function for each character p
    a = 255 & // any intermediate result is converted to numeric and truncate to a byte          
   // evaluate all possible results (then choose one bases on the current character)
   [a,   // NOP, if unexpected char 'a' remains the same
    ~a,  // tilde == binary not (will give a result wider than a byte)
    a*2, // < shift left is *2 (can give a result wider than a byte) 
    a/2, // > shift right is /2 (can give a non integer result)
    a *257 / 16  // move nibbles around (will give a result wider than a byte)
   ] // array of all results
   [1+'!<>@'.indexOf(c)] // find index to get the correct result
  ) // end map, returns an array in any case
    // eventually a single element array containg a
  | a // return accumulator
Test program:<input id=I><button onclick='go(I.value)'>go</button>
<pre id=O></pre>

edc65
źródło
1

Kryształ, 139 bajtów

def f x
b=0_u8
x.chars.each do|c|
b=case c
when'!'
~b
when'>'
b>>1
when'<'
b<<1
when'@'
b<<4|b>>4
else raise ""
end
end
puts b
end
kirbyfan64sos
źródło
1

C # 193

void Main(){byte a=0;foreach(var c in Console.ReadLine()){if(c=='!')a=(byte)~a;if(c=='>')a=(byte)(a>>1);if(c=='<')a=(byte)(a<<1);if(c=='@')a=(byte)(((a&240)>>4)|((a&15)<<4));}Console.Write(a);}
Stephan Schinkel
źródło
2
Nie potrzebujesz using System;ani czegoś takiego, aby uzyskać dostęp Console.ReadLinei Console.Writebez System.prefiksu?
Alex A.
Wydaje mi się również, że nie powinieneś rzucać do bytekażdej operacji, ale mogę się mylić.
Alex A.
1

Lua, 344 char

a=string.rep("0",8)
t=io.read()
f={["!"]=function()local s="";for j=1,8 do s=s..(a:sub(j,j)=="0"and"1"or"0") end;return s end,[">"]=function() return "0"..a:sub(1,7) end,["<"]=function()return a:sub(2,8).."0"end,["@"]=function()return a:sub(5,8)..a:sub(1,4)end}
for i=1,#t do a=(f[t:sub(i,i)]or function()return a end)()end
print(tonumber(a,2))

Zainspirowany przez @Beta Decay użycie akumulatora strunowego, ponieważ lua nie ma typu bajtów. Prawdopodobnie można by grać w golfa przy użyciu mniejszej liczby funkcji.

Delya Erricson
źródło
1

R 194 bajtów

b<-readline();A<-rep(0,8);s<-strsplit(b,"")[[1]];for(r in s){if(r=="!")A<-(A+1)%%2;if(r==">")A<-c(0,A)[1:length(A)];if(r=="<")A<-c(A,0)[-1];if(r=="@")A<-c(A[5:8],A[1:4])};print(sum(A*(2^(7:0))))

bez golfa

b <- readline()
A <- rep(0, 8) 
s <- strsplit(b, "")[[1]]
for (r in s) {
    if (r == "!")
        A <- (A + 1) %% 2
    if (r == ">")
        A <- c(0, A)[1:length(A)]
    if (r == "<")
        A <- c(A, 0)[-1]
    if (r == "@")
        A <- c(A[5:8], A[1:4])
}
print(sum(A*(2^(7:0))))
mawir
źródło
Wszystkie <-można zastąpić =tutaj, zmniejszając w ten sposób kod o 7 bajtów. Dodatkowo możesz być w stanie zastąpić serię ifinstrukcji jednym wywołaniem do switch(as in A=switch(r,"!"=(A+1)%%2, ...))
plannapus 20.04.16
Wynikowy b=readline();A=rep(0,8);s=strsplit(b,"")[[1]];for(r in s)A=switch(r,"!"=(A+1)%%2,">"=c(0,A)[1:length(A)],"<"=c(A,0)[-1],"@"=c(A[5:8],A[1:4]),A);print(sum(A*(2^(7:0))))to 167 bajtów.
plannapus
1

RPL, 170,5 bajtów

Dane wejściowe należy wprowadzić jako ciąg na poziomie 1.

\<< DEC 8 STWS \-> S 
    \<< #0d 1 S SIZE 
        FOR I "!><@" S I DUP SUB POS 1 + { \<< \>> NOT SR SL \<< DUP #16d / SWAP #16d * + \>> } SWAP GET EVAL NEXT \>> 
\>>
Jason
źródło
1

K, 57 bajtów

To poczatek:

0{y+2*x}/(8#0){((~:;{-1_0,x};{1_ x,0};4!;{x})"!><@"?y)x}/

testowane przy użyciu Kona:

  f:0{y+2*x}/(8#0){((~:;{-1_0,x};{1_ x,0};4!;{x})"!><@"?y)x}/
...
  f'("!";"!>>";"!<@";"!nop!&6*!")
255 63 239 255

Mogę być w stanie poradzić sobie lepiej w K5, ale jest to złożona seria kompromisów - na przykład konwersja wartości binarnej na dziesiętną jest równie łatwa 2/, ale zachowanie ?utrudnia obsługę domyślnego przypadku wyszukiwania instrukcji.

JohnE
źródło
1

PHP, 189 bajtów

<? $c='00000000';foreach(str_split($argv[1])as$a){$a=='!'&&$c=strtr($c,'01','10');$a=='<'&&$c=substr($c.'0',1);$a=='>'&&$c=substr('0'.$c,0,8);$a=='@'&&$c=substr($c.$c,4,8);}echo bindec($c);

Nie chodzi o to, że pobije wiele odpowiedzi, tylko o trening

Einacio
źródło
1

HPPPL , 302 294 bajtów

#pragma mode(separator(.,;)integer(d8))EXPORT b()BEGIN print();local p,j,a;a:=#0d;INPUT({{p,[2]}});for j from 1 to dim(p)do c:=p(j);case if c==33 then a:=BITNOT(a)end if c==62 then a:=BITSR(a,1)end if c==60 then a:=BITSL(a,1)end if c==64 then a:=BITSL(a,4)+BITSR(a,4)end end;end;print(a*1);END;

Nie golfowany:

// make sure integers are unsigned 8 bit decimal numbers
#pragma mode( separator(.,;) integer(d8) ) 
EXPORT b()
BEGIN
  print();
  local p,j,a;
  a:=#0d;                         // set a to integer value 0
  INPUT({{p,[2]}});               // open input dialog treating input as string ( type [2])
  for j from 1 to dim(p) do
    c:=p(j);
    case
      if c==33 then a:=BITNOT(a) end             // !
      if c==62 then a:=BITSR(a,1) end            // >
      if c==60 then a:=BITSL(a,1) end            // <
      if c==64 then a:=BITSL(a,4)+BITSR(a,4) end // @
    end;
  end;
  print(a*1); // converts to proper output by promoting to non integer format
              // print(a) would result in
              // #239:8d for 239 if the default bit size is not set to 8 bits decimal
              // indicating an 8 bit unsigned decimal integer, or
              // #239d if the default bit size is already set to 8 bits decimal

END;

Polecenie wejścia HPPPL

Wyjście HPPPL do terminala

Ta odpowiedź zapewnia, że ​​HP Prime używa 8-bitowych liczb całkowitych bez znaku, nawet jeśli tryb jest ustawiony na np. 64 bity przez użytkownika. Jeśli kalkulator jest skonfigurowany ręcznie do używania liczb całkowitych dziesiętnych bez znaku, wówczas pragmapolecenie można pominąć. Jeśli dane wyjściowe nie muszą ściśle przestrzegać formatu, to a*1na końcu może być po prostu a. Pomnożenie wyniku przez 1 gwarantuje, że dane wyjściowe nie będą zgodne z danymi wyjściowymi dla wartości całkowitych. printPolecenia w wierszu 4 można również pominąć, jeżeli terminal nie muszą być wyczyszczone przed wydrukowaniem wynik. Jeśli dozwolone jest przekazywanie programu jako argumentu ciągu, INPUTpolecenie można również pominąć.

Jest to najkrótsza wersja z wejściem i właściwym wyjściem, bez argumentu pragma (jeśli domyślnie kalkulator jest ustawiony na Uint8:

243 bajty:

EXPORT b()BEGIN local p,j,a;a:=#0d;INPUT({{p,[2]}});for j from 1 to dim(p)do c:=p(j);case if c=33 then a:=BITNOT(a)end if c=62 then a:=BITSR(a,1)end if c=60 then a:=BITSL(a,1)end if c=64 then a:=BITSL(a,4)+BITSR(a,4)end end;end;print(a*1);END;
ML
źródło
1

Perl 6, 96 89 bajtów

{my $a=0;$a=(+^*,*+<1,*+>1,{$_+<4+$_+>4},{$_})["!<>@".index($_)//4]($a)%256 for .comb;$a}

Stare rozwiązanie:

{my $a=0;$a=(255-*,*+<1+&255,*+>1,{$_+&15+<4+$_+>4},{$_})["!<>@".index($_)//4]($a)for .comb;$a}
bb94
źródło
1

C #, 119 bajtów

i=>{var a=0;foreach(var c in i){if(c=='!')a=~a;if(c=='>')a>>=1;if(c=='<')a<<=1;if(c=='@')a=a<<4|a>>4;a&=255;}return a;}

Inne wersje próbowałem, ale potrzebuję więcej bajtów:

Func<string,int>C=i=>{var a=0;foreach(var c in i){switch(c){case'!':a=~a;break;case'<':a<<=1;break;case'>':a>>=1;break;case'@':a=a<<4|a>>4;break;}a&=255;}return a;};

// This is, despite having the worst score, my personal favourite :D
Func<string,int>D=i=>{var f=new Dictionary<char,Func<int,int>>{{'!',q=>~q},{'<',q=>q<<1},{'>',q=>q>>1},{'@',q=>q<<4|q>>4}};var a=0;foreach(var c in i)if(f.ContainsKey(c))a=f[c](a)&255;return a;};
Stefan
źródło
1

Python 2.7.3, 104 bajty

Posiadanie kodu w ciągach do oceny wygląda dość brudno, ale działa: D

a=0
for c in raw_input():a=eval({'!':'~a','<':'a<<1','>':'a>>1','@':'a<<4|a>>4'}.get(c,'a'))&255
print a

Oto dane wyjściowe (i dane wejściowe faktycznie…)

I tak, to naprawdę działa na RaspberryPi :)

Przykładowe dane wyjściowe

Stefan
źródło