Programmieren mit Bits und Bytes


40

In dieser Herausforderung werden Sie einen Dolmetscher für eine einfache Sprache schreiben, die ich erfunden habe. Die Sprache basiert auf einem einzelnen Akkumulator A, der genau ein Byte lang ist. Zu Beginn eines Programms ist A = 0. Dies sind die Sprachanweisungen:

!: Inversion

Dieser Befehl invertiert einfach jedes Bit des Akkumulators. Jede Null wird zu einer Eins und jede wird zu einer Null. Einfach!

>: Nach rechts verschieben

Diese Anweisung verschiebt jedes Bit in A um eine Stelle nach rechts. Das Bit ganz links wird zu einer Null und das Bit ganz rechts wird verworfen.

<: Nach links verschieben

Dieser Befehl verschiebt jedes Bit in A um eine Stelle nach links. Das Bit ganz rechts wird zu einer Null und das Bit ganz links wird verworfen.

@: Swap Nybbles

Dieser Befehl tauscht die oberen vier Bits von A mit den unteren vier Bits aus. Wenn beispielsweise A ist 01101010und Sie ausführen @, ist A 10100110:

 ____________________
 |                  |
0110 1010    1010 0110
      |_______|

Das sind alle Anweisungen! Einfach, richtig?

Regeln

  • Ihr Programm muss zu Beginn einmalig Eingaben akzeptieren . Dies wird eine Codezeile sein. Dies ist kein interaktiver Interpreter! Sie können Eingaben nur einmal annehmen und müssen nach Ausführung dieser Zeile nicht zum Anfang zurückkehren.
  • Ihr Programm muss diese Eingabe auswerten. Jedes oben nicht erwähnte Zeichen wird ignoriert.
  • Ihr Programm sollte dann den Endwert des Akkus dezimal ausgeben.
  • Es gelten die üblichen Regeln für gültige Programmiersprachen.
  • Standardlücken sind nicht zulässig.
  • Dies ist , die kleinste Anzahl von Bytes gewinnt.

Hier sind einige kleine Programme, mit denen Sie Ihre Beiträge testen können. Vor dem Pfeil steht der Code, danach das erwartete Ergebnis:

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

Genießen!


Ich gehe davon aus, ! -> 255dass wir hier 8 Bits pro Byte verwenden? Die Frage ist nicht explizit.
Toby Speight

3
@TobySpeight Ein Byte besteht per Definition aus 8 Bits.
HyperNeutrino

Antworten:


15

Pyth, 36 35 Bytes

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

Kabelbaum testen

Die interne Darstellung des Akkumulators ist eine ganze Zahl. Diese Ganzzahl wird bei jeder Iteration wie gewünscht um 256 geändert. Die Operationen durchgeführt werden -G-1, G/2, G*2und Gumgerechnet auf der Basis 16, umgekehrt, und konvertieren zurück zur Basis 10, wobei Gder Akkumulator ist.

Ich habe den Gedanken daran, alles andere zu ignorieren, verpasst. Dies wurde behoben. Danke, @Dennis.


Ist also -G-1kürzer als ~Gin Pyth? Das bezweifle ich etwas.
CalculatorFeline

Der fragliche Code ist tatsächlich t_G, wo _Negation ist und tist -1. In Pyth ~bedeutet das etwas völlig anderes.
isaacg

Ich meinte Python ~(bitweise NICHT)
CalculatorFeline

@CalculatorFeline Mein Punkt war, dass es in Pyth keine 1-Zeichen-Funktion mit diesem Effekt gibt, also ist der obige Code (zumindest für diese Operation) so gut wie er wird.
Isaacg

13

C 96

Angenommen, ASCII-Eingabe (oder kompatible Eingabe):

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

Ordentlicher:

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

Im Grunde ist es nur eine Sammlung verschachtelter ternärer Ausdrücke. Ich inkrementiere den erhaltenen Wert, getchar()so dass ein EOF (-1) einen Wert von Null ergibt und das Programm beendet wird.

(ideone link)


1
Ich habe die Herausforderung selbst ausprobiert und fast genau den gleichen Code geschrieben. Btw. Ihr Programm lässt das Bit beim Hochschalten nicht fallen (Eingabe: !<>sollte ergeben 127und nicht 255). Definieren Sie entweder Ihr aals char, oder verwenden Sie die Linie a&=255(und verwenden Sie %u), um den richtigen Effekt zu erzielen. Auch können Sie Ihre Negation verkürzen a^255zu ~a. a>>4&15ist auch kürzer als deine (a&240)/16.
MarcDefiant

Ah, guter Punkt. Es stellte sich heraus, dass es effizienter war, die unteren 8 Bits bei jeder Iteration auszublenden.
Squeamish Ossifrage

1
In diesem Fall können Sie sogar die %u%hhu
Formatzeichenfolge

1
Ich habe es gerade gesehen, aber Sie können es auch a/16|a*16anstelle von verwenden a/16|(a&15)*16. Die wenigen Bits oben werden von der entfernt &255.
MarcDefiant

1
Eine kleine Verbesserung: a*257/16Ist ein Byte kürzer als a/16|a*16.
Toby Speight

11

Python 3, 133 Bytes

Verwendet ein Wörterbuch, um einen Mangel an Groß- / Kleinschreibung in Python auszugleichen. Sehen Sie hier mehr .

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

Der Akkumulator ist eine Zeichenfolge, die am Ende in eine Zahl zur Basis 10 umgewandelt wird.

Beispiel I / O:

$ python3 bitsnbytes.py
!
255
$ python3 bitsnbytes.py
!>>
63
$ python3 bitsnbytes.py
!<@
239
$ python3 bitsnbytes.py
!nop!&6*!
255

Wenn es ein echter, interaktiver Dolmetscher wäre, wäre es for i in sys.stdin::)
Zizouz212

4
@ Zizouz212 Ich glaube du meinst, wenn es interaktiv war; es sieht für mich wie ein echter Dolmetscher aus. ;)
Alex A.

9

Javascript (ES6), 80 91 90 Bytes

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

So kurz wie es nur geht. Definiert eine anonyme Funktion, die das Programm als Eingabe verwendet.

  • Für !, nimmt x XOR 255, als JS ~würde xeine 32-Bit-Zahl in Betracht ziehen .
  • Für <multipliziert xmit 2 und nimmt das Ergebnis mod 256.
  • Denn >verschiebt die Bits um x1 Bit wirklich nach rechts.
  • Für @Böden x/16und fügt es hinzu x%16*16.

Vielen Dank an @vihan, der vorgeschlagen hat reduce, ein Byte zu speichern.


Mit können Sie <ca. 4 Bytes speichern. Durch die Verwendung von "Reduzieren" werden möglicherweise auch einige Bytes
gespart

1
@vihan Meinst du <anstelle von ==? Wenn ja, würde das nicht funktionieren, da No-Op-Zeichen eine Operation falsch ausführen würden. Ich habe das in meiner vorherigen 80-Byte-Lösung verwendet.
ETHproductions

Ist es nicht der Standard für ES6-Fettpfeile bei PPCG, den Sie definieren müssen?
MayorMonty

@SpeedyNinja Ich kenne keinen solchen Standard, aber wenn Sie mich auf einen Beitrag über einen verweisen könnten, werde ich meine Antwort ändern.
ETHproductions

8

CJam, 37 Bytes

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

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

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#

8

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

Wow, das hat eine Menge Golf gespielt! Vielen Dank an alle, die mir Vorschläge gemacht haben! Ich schätze es sehr!

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

31 (!) Bytes durch Optimieren des Nibble-Swaps mit bitweisen Operationen im Gegensatz zu langwierigen Integer.???Methoden.

Golf 72 (!!!!) Zeichen durch Entfernen der unnötigen Zeichenfolge zum Tauschen von Knabbern. Viel besser als zuvor !?

45 (!!) Zeichen durch Entfernen von java.util.Scannerund Ablesen von System.indirekt abgelegt . Beachten Sie, dass jetzt, da der Lambda-Ausdruck nicht mehr vorhanden ist, Java 8 nicht mehr benötigt wird! Einfach nur Java 1 würde reichen!

Hat dank @bmarks 7 Zeichen durch Erstellen einer Klasse (default)(entferntes publicSchlüsselwort) erzielt

Golfen Sie 120 (!!!!!!!) Zeichen, indem Sie all diese langwierigen IntegerKlassenoperationen im Bit drehen 255 - a. Das ist jetzt viel kürzer!

15 (!) Zeichen durch Konvertieren von Verschiebungen in Multiplikation und Division, Entfernen der geschweiften Klammern aus der while-Anweisung und Lokalisieren ainnerhalb der mainMethode.

Ungolfed 9 = (Zeichen aufgrund eines Problems mit der Linksverschiebung, bei dem das am weitesten links liegende Byte nicht verworfen wird. Deshalb tue ich das jetzt mod (256). Durch die Rechtsverschiebung wird die resultierende Zahl um ein Bit kürzer als zuvor, sodass modbei der Rechtsverschiebung keine Verwendung erforderlich ist . Mein Nibble-Swap-Ding tauscht die letzten 4 Bits und das vorletzte Nibble aus und and (&)schneidet alle anderen Bits ab. Mein Inversionsprogramm verursacht keine Probleme, wenn die ursprüngliche Zahl kleiner als 256 ist.

Golfed 31 35 Zeichen dank @Geobits durch Umwandlung switchAussage zu vielen ternären Aussagen und auch Zeichen zu Ints Umwandlung, die Literale zu verkürzen.

Golfed 7 Zeichen durch unnötige Entfernung &240im knabbern swap ( (a&240)>>4zu a>>4und Umwandlung (a&15)<<4zu a<<4&240. Die letzte Änderung stammt golfed nur wenn ein Zeichen.

Golfed 1 char durch unnötiges Entfernen =in a /= 2, weil a = a /= 2gleichbedeutend mit a = a / 2.

Golf 2 Zeichen durch Drehen printlnan print.

Golf 2 Zeichen durch Entfernen von versehentlich a=in a=255-a( a=a=255-aentspricht a=255-a)

1 Char durch Drehen a<<4&240in Golf a%16<<4.

Golf 1 Zeichen durch Hinzufügen von Klammern an der Außenseite der ternären Anweisung und zu tun %256. Auf diese Weise ist das %16im linken Verschiebungsteil des Knabbertauschs nicht erforderlich. Die Klammern addieren 2 Zeichen und die %16spart 3 Zeichen.

Golfed 3 Zeichen , indem classauf interfaceund Entfernen publicmit Feature - Methode Java 8 statische Schnittstelle. Danke an @TheNumberOne (kein Kommentar, aber Antwort auf "Tipps zum Golfen in Java"


Ich denke nicht, dass die Klasse öffentlich sein muss. Auch ich denke , wenn man eine einen Integer anstelle eines int machen, könnten Sie tun a.parseInt, a.toString usw. statt Integer.parseInt, Integer.toString usw.
bmarks

Danke für den ersten Vorschlag; Ich werde jedoch alle IntegerKlassenmethoden entfernen .
HyperNeutrino

Vielleicht können Sie while ((i = System.in.read ())> 10) anstelle von! = 10 ausführen, um ein Byte zu speichern?
bmarks

Gute Idee, aber irgendetwas unter 10 wird dazu führen, dass das Programm beendet wird, und ich soll andere Zeichen ignorieren und dann nicht das Ende der Welt erreichen (oder zumindest mein Programm :)). Vielleicht gibt es keine gültigen ASCII-Zeichen unter 10.
HyperNeutrino

4
Es lohnt sich fast nie, eine switchWeile Golf zu spielen. Der case/ breaksind einfach zu lang. Sie sollten in der Lage sein, einen Haufen zu retten, indem Sie das Ganze zu einem Dreiklang machen. so etwas wiea=i=='!'?255-a:i==62?a/2:i=='<'?a*2%256:i=='@'?(a&240)>>4|(a&15)<<4:a;
Geobits

7

Rust, 121 115 Bytes

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}

Probelauf:

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

Ungolfed:

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
}

Überraschend kurz für Rust. Nichts anderes wirklich Interessantes als die Tatsache, dass ich heute mehr Vorrangregeln gelernt habe - wer wusste, dass (a>>b)|ces dasselbe ist wie a>>b|c?

Aus einem Byte durch Ändern n>>=1von rasiert n/=2; Dies ist jedoch mit der Multiplikation nicht möglich, da ein arithmetischer Überlauf in Rust eine Panik (dh ein Absturz) ist.


2
Die Sache mit dem Vorrang ist sinnvoll, wenn Sie sich selbst davon überzeugen, dass >>es sich um eine Art Spaltung und |eine Art Addition handelt.
Lynn

6

HP 41C / CV / CX (? Bytes, 42 Schritte)

Rein zum Kichern, hier für den HP 41C / CV / CX-Rechner. (Benötigt entweder das Extended Functions-Modul oder einen 41CX für die ATOX-Funktion.) Der Rechner meldet leider keine Programmgrößen in Bytes.

Legen Sie Ihr Programm in das Alpha-Register, was ein wenig schwierig ist, da es keine Möglichkeit gibt, es zu betreten! oder @ direkt von der Tastatur (verwenden Sie XTOA mit den ASCII-Codes 33 bzw. 64, um sie anzuhängen).

In den Schritten 08 und 10 können ungültige Opcodes ignoriert werden. Entfernen Sie sie, um 2 Schritte zu speichern, aber das Programm stürzt bei ungültiger Eingabe ab.

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

6

Python 2, 79 Bytes

Mir ist aufgefallen, dass ich in Python etwas sehr Ähnliches gemacht habe . Dies ist nur ein Teil meiner Ruby-Antwort , aber im Übrigen die kürzeste Python-Antwort: D

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

Der Unterschied zur Ruby-Version besteht darin, dass diese ungültige Anweisungen beim Durchlaufen der Eingabe nicht ignoriert. Stattdessen nehme ich die Tatsache zunutze , dass Python zurückzukehren neigt -1statt , nilwenn es keine Übereinstimmung - Der aktuelle Wert der aan der Rückseite des Ergebnisses Array angehängt wird, so dass alle ungültigen Anweisungen Karten auf den gleichen, unveränderten Wert.


4

Python 3, 124 94 93 Bytes

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)

"!" ist gleichbedeutend mit Subtrahieren von 255.
"<" ist gleichbedeutend mit Multiplizieren mit 2. Aber 8-Bit-Register bedeutet Mod 256.
">" ist gleichbedeutend mit ganzzahliger Division durch 2.
"@" bedeutet Verschieben der letzten 4 Bits ( a%16) um 4 Bits ( *16) und Addieren der ersten vier Bits ( a/16).

EDIT (schamloses Kopieren lesen)
Sah die andere Antwort in Python (durch Beta-Zerfall). Es ist eine sehr effektive Methode, Schalterfälle mithilfe eines Wörterbuchs zu simulieren. Damit können wir schreiben

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

Danke, Beta Decay.


Egal welche Operation du machst, du musst den Mod reduzieren 256oder? Also , warum das nicht am Ende: a={"!":255-a,"<":a*2,">":a//2,"@":(a%16)<<4+a>>4}.get(i,a)%256. Dies erspart Ihnen sofort ein Byte (weil Sie dies a*2anstelle von tun werden a<<1) ... aber @ danieros Antwort zeigt auch, dass wenn Sie es auf diese Weise tun, es (a%16)<<4auf nur verkürzt werden kann a<<4, da jedes Bit 16 oder größer eliminiert wird, sobald Sie multiplizieren es um 16 und verkleinere es um mod 256. Schön! Sie können jetzt auch 255-adurch -1-a... oder besser durch nur ersetzen ~a. Insgesamt sollten Sie mit diesen Vorschlägen 9 Byte einsparen.
Mathmandan

3

Haskell, 89 Bytes

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

Anwendungsbeispiel: f "!>>"->63


3

Rust, 111 Bytes

Eher ein Kommentar zur Antwort von @ Doorknob, aber ich habe keinen Repräsentanten für Kommentare, da ich gerade ein Konto erstellt habe.

Man kann 10 Bytes seiner Rust-Lösung mit den folgenden Mitteln absparen:

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}

Ich dachte, wir könnten mit fold sogar noch kürzer werden ( doc.rust-lang.org/std/iter/trait.Iterator.html#method.fold ), aber überraschenderweise macht es ein bisschen länger.
user4867444

3

Python 3, 127 Bytes

Edit: Kurzschluss, danke @Jakube

Edit2: fix, danke @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)

Vielleicht liegt das an der neuen Zeile von Windows. Das sind plus zwei Bytes. Ich werde das nächste Mal diesen Bytezähler verwenden. :-) Vielen Dank.
Uno20001

Beachten Sie, dass dies nicht das Bit ganz links nicht verwerfen , wenn Verschiebung nach links, so !<gibt , 510während es sein sollte254
Rohcana

Ich hoffe jetzt schon. Entschuldigung für meine Fehler, dies ist meine erste "Golf" -Herausforderung.
uno20001

3

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

Formatiert:

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

#fund #f0Hexadezimalzahlen für die Halbbytes sind, .bytekonvertiert eine Ganzzahl in ein Byte. Ich bin glücklich, dass Bytes .stringAttribut bereits die vorzeichenlose Darstellung eines Bytes verwendet. Ceylon bietet auch eine switch-Anweisung ohne Fall-Through und eine Zeichenfolge ist eine Liste von Zeichen, die iteriert werden kann.

Ich habe auch versucht, diese langen Shift-Methodennamen mithilfe eines Aliasing-Imports zu reduzieren, aber dies wird tatsächlich 7 Byte länger:

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

Formatiert:

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

Dies kann nützlich sein, wenn wir diese Methoden etwas häufiger benötigen.


3

Rubin, 81 73 Bytes

So viel einfacher - keine Bewertung! Für jedes gültige Zeichen in der Eingabe wertet es jede Anweisung aus und findet die entsprechende Anweisung über den Index von $&(das aktuelle Zeichen in der Eingabe).

a=0
gets.scan(/[!><@]/){a=[~a,a/2,a*2,a*16+a/16]["!><@".index$&]&255}
p a

1
Das ist genial Viel kürzer als anderswo. 2 Upvotes von mir!
EDC65

Wie können Sie doppelt abstimmen ...?
HyperNeutrino,

@ JamesSmith Er bezieht sich wahrscheinlich auf diese und meine Python-Antwort :)
daniero

@ Danerio Ich verstehe.
HyperNeutrino

2

STATA, 197 Bytes

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

Ungolfed

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

Funktioniert nicht mit dem Online-Dolmetscher und erfordert den nicht freien Standard-Dolmetscher. Dies wäre mit tatsächlichen bitweisen Operationen etwas einfacher, aber ich denke nicht, dass sie für die meisten gängigen Anwendungen von STATA zu nützlich sind.


Warum funktioniert der Online-Dolmetscher nicht?
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)

Verschachtelte ternäre Operatoren werden Anweisungen zugeordnet.

BITWISE AND wird verwendet, um unseren Zahlentyp auf ein einzelnes Byte zu beschränken.


2

Julia, 117 94 86 73 Bytes

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)

Dies ist eine anonyme Funktion, die eine Zeichenfolge akzeptiert und eine Ganzzahl zurückgibt. Um es aufzurufen, weisen Sie es einer Variablen zu.

Ungolfed:

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

8 Bytes dank Sp3000 und 13 dank Dennis gespart!


2

JavaScript (ES6), 76 81

Als unbenannte Funktion, die den Akkumulatorwert zurückgibt

Dies ist eine Portierung der superschlauen Antworten von @daniero (die viel zu wenig positive Stimmen haben)

Bonus: Sie können einen Anfangswert des Akkus übergeben. Wenn nicht bestanden, ist der Startwert 0, wie spezifisch.

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

Teste das folgende Snippet in einem beliebigen EcmaScript 6-Browser (in Firefox getestet)

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>


1

Kristall, 139 Bytes

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

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

2
Müssen Sie using System;oder so etwas nicht zugreifen Console.ReadLineund Console.Writeohne das System.Präfix?
Alex A.

Auch scheint mir, dass Sie nicht bytefür jede Operation besetzen müssen, aber ich könnte mich irren.
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))

Inspiriert von der Verwendung eines String-Akkumulators durch @Beta Decay, da lua keinen Bytetyp hat. Könnte wahrscheinlich mit weniger Funktionen mehr Golf spielen.


1

R, 194 Bytes

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

ungolfed

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

Hier <-können alle ersetzt =werden, wodurch der Code um 7 Byte reduziert wird. Außerdem können Sie möglicherweise die ifAnweisungsreihe durch einen Aufruf von switch(wie in A=switch(r,"!"=(A+1)%%2, ...))
plannapus 20.04.16

Das Ergebnis 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))))sind 167 Bytes.
Plannapus

1

RPL, 170,5 Bytes

Die Eingabe sollte als Zeichenfolge auf Ebene 1 eingegeben werden.

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

1

K, 57 Bytes

Es ist ein Anfang:

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

getestet mit 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

In k5 könnte ich es vielleicht besser machen, aber es ist eine komplexe Reihe von Kompromissen - zum Beispiel ist das Konvertieren von Binär in Dezimal so einfach wie 2/, aber das Verhalten von ?macht es schwieriger, einen Standardfall für die Befehlssuche zu behandeln.


1

PHP, 189 Bytes

<? $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);

Es ist nicht so, dass es viele Antworten übertreffen würde, sondern nur zum Üben


1

HPPPL , 302 294 Bytes

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

Ungolfed:

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

HPPPL-Eingabebefehl

HPPPL-Ausgabe zum Terminal

Diese Antwort stellt sicher, dass der HP Prime 8-Bit-Ganzzahlen ohne Vorzeichen verwendet, auch wenn der Modus vom Benutzer auf z. B. 64 Bit festgelegt wurde. Wenn der Taschenrechner manuell mit vorzeichenlosen 8-Bit-Dezimalzahlen eingerichtet wurde, kann der pragmaBefehl weggelassen werden. Wenn die Ausgabe nicht unbedingt dem Format entsprechen muss, kann das a*1am Ende einfach sein a. Durch Multiplizieren des Ergebnisses mit 1 wird lediglich sichergestellt, dass die Ausgabe nicht der internen Ausgabe für ganzzahlige Werte folgt. Der printBefehl in Zeile 4 kann auch weggelassen werden, wenn das Terminal vor dem Ausdruck des Ergebnisses nicht gelöscht werden muss. Wenn die Übergabe des Programms als String-Argument zulässig ist, kann der INPUTBefehl auch weggelassen werden.

Dies ist die kürzeste Version mit Eingabe und korrekter Ausgabe ohne das Pragma-Argument (wenn der Taschenrechner standardmäßig auf Uint8 eingestellt ist):

243 Bytes:

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;

1

Perl 6, 96 89 Bytes

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

Alte Lösung:

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

1

C #, 119 Bytes

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

Andere Versionen, die ich ausprobiert habe, aber mehr Bytes benötigen:

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

1

Python 2.7.3, 104 Bytes

Code in Strings zu haben, der ausgewertet werden soll, sieht ziemlich schmutzig aus, funktioniert aber: 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

Hier ist die Ausgabe (und Eingabe tatsächlich ..)

Und ja, es läuft wirklich auf einem RaspberryPi :)

Beispielausgabe

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.