Pemrograman dengan Bits dan Bytes

40

Dalam tantangan ini, Anda akan menulis penerjemah untuk bahasa sederhana yang saya buat. Bahasa ini didasarkan pada akumulator tunggal A, yang panjangnya tepat satu byte. Pada awal program, A = 0. Ini adalah instruksi bahasa:

!: Pembalikan

Instruksi ini hanya membalikkan setiap bit akumulator. Setiap nol menjadi satu dan setiap orang menjadi nol. Sederhana!

>: Shift Kanan

Instruksi ini menggeser setiap bit di A one place ke kanan. Bit paling kiri menjadi nol dan bit paling kanan dibuang.

<: Shift Kiri

Instruksi ini menggeser setiap bit di A satu tempat ke kiri. Bit paling kanan menjadi nol dan bit paling kiri dibuang.

@: Swap Nybbles

Instruksi ini menukar empat bit teratas A dengan empat bit terbawah. Misalnya, Jika A adalah 01101010dan Anda mengeksekusi @, A akan menjadi 10100110:

 ____________________
 |                  |
0110 1010    1010 0110
      |_______|

Itu semua instruksinya! Sederhana bukan?

Aturan

  • Program Anda harus menerima input sekali di awal. Ini akan menjadi baris kode. Ini bukan penerjemah interaktif! Anda hanya dapat menerima input satu kali dan tidak perlu mengulang kembali ke awal setelah baris itu dieksekusi.
  • Program Anda harus mengevaluasi kata input. Setiap karakter yang tidak disebutkan di atas diabaikan.
  • Program Anda kemudian harus mencetak nilai akhir akumulator, dalam desimal.
  • Aturan biasa untuk bahasa pemrograman yang valid berlaku.
  • Celah standar tidak diijinkan.
  • Ini adalah , jumlah byte terkecil yang menang.

Berikut adalah beberapa program kecil untuk menguji kiriman Anda. Sebelum panah adalah kode, setelah itu adalah hasil yang diharapkan:

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

Nikmati!

bitnbites
sumber
Saya menduga ! -> 255bahwa kita akan menggunakan 8 bit per byte di sini? Pertanyaannya tidak eksplisit.
Toby Speight
3
@ TokySpeight Byte, menurut definisi, adalah 8 bit.
HyperNeutrino

Jawaban:

15

Pyth, 36 35 byte

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

Uji harness

Representasi internal akumulator adalah bilangan bulat. Integer ini dimodifikasi oleh 256 pada setiap iterasi, sesuai keinginan. Operasi yang dilakukan adalah -G-1, G/2, G*2dan Gdikonversi ke basis 16, terbalik, dan dikonversi kembali ke pangkalan 10, di mana Gadalah akumulator.

Saya melewatkan baris tentang mengabaikan segala sesuatu yang lain. Ini telah diperbaiki. Terima kasih, @Dennis.

isaacg
sumber
Jadi -G-1lebih pendek dari ~Gpada Pyth? Saya agak meragukannya.
CalculatorFeline
Kode yang dimaksud sebenarnya adalah di t_Gmana _negasi dan tberada -1. Dalam Pyth, ~berarti sesuatu yang sama sekali berbeda.
isaacg
Maksud saya Python ~(bitwise NOT)
CalculatorFeline
@CalculatorFeline Maksud saya adalah tidak ada fungsi 1 karakter dengan efek di Pyth, jadi kode di atas (setidaknya untuk operasi itu) sama baiknya dengan yang akan didapat.
isaacg
13

C, 96

Dengan asumsi input ASCII (atau yang kompatibel):

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

Lebih rapi:

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

Pada dasarnya itu hanya kumpulan ekspresi tersier bersarang. Saya menambah nilai yang diperoleh dari getchar()sehingga EOF (-1) menghasilkan nilai nol dan program keluar.

(tautan ideone)

lubang keras melengking
sumber
1
Saya mencoba tantangan itu sendiri dan saya menulis kode yang hampir persis sama. Btw. program Anda tidak menjatuhkan bit ketika bergeser ke atas (input: !<>harus menghasilkan 127dan tidak 255). Tetapkan asebagai Anda char, atau gunakan baris a&=255(dan gunakan %u) untuk mendapatkan efek yang benar. Anda juga dapat mempersingkat negasi Anda a^255menjadi ~a. a>>4&15juga lebih pendek dari Anda (a&240)/16.
MarcDefiant
Ah, poin bagus. Ternyata itu lebih efisien untuk menutupi 8 bit yang lebih rendah pada setiap iterasi.
squeamish ossifrage
1
Dalam hal ini Anda bahkan dapat menggunakan format string %ubukan%hhu
MarcDefiant
1
Aku hanya melihat sekarang, tetapi Anda juga dapat menggunakan a/16|a*16bukan a/16|(a&15)*16. Beberapa bit di atas bisa dihapus oleh &255.
MarcDefiant
1
Peningkatan kecil: a*257/16satu byte lebih pendek dari a/16|a*16.
Toby Speight
11

Python 3, 133 byte

Menggunakan kamus untuk menebus kurangnya sintaks kasus sakelar di Python. Lihat lebih lanjut di sini .

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 adalah string yang diubah menjadi nomor basis 10 di akhir.

Contoh I / O:

$ python3 bitsnbytes.py
!
255
$ python3 bitsnbytes.py
!>>
63
$ python3 bitsnbytes.py
!<@
239
$ python3 bitsnbytes.py
!nop!&6*!
255
Peluruhan Beta
sumber
Jika itu benar-benar penerjemah interaktif, itu pasti for i in sys.stdin::)
Zizouz212
4
@ Zizouz212 Saya percaya maksud Anda jika itu interaktif; kelihatannya seperti penerjemah nyata bagi saya. ;)
Alex A.
9

Javascript (ES6), 80 91 90 byte

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

Cukup pendek yang bisa didapat. Menentukan fungsi anonim yang menjadikan program sebagai input.

  • Untuk !, ambil x XOR 255, karena JS ~akan mempertimbangkan xnomor 32-bit.
  • Untuk <, gandakan xdengan 2 dan ambil hasilnya mod 256.
  • Sebab >, benar-benar menggeser bit x1 bit ke kanan.
  • Untuk @, lantai x/16dan menambahkannya ke x%16*16.

Terima kasih kepada @vihan karena menyarankan penggunaan reduceuntuk menyimpan byte.

Produksi ETH
sumber
Anda dapat menggunakannya <untuk menghemat sekitar 4 byte. Menggunakan pengurangan mungkin juga menghemat beberapa byte
Downgoat
1
@ Vihan Apakah maksud Anda <di tempat ==? Jika demikian, itu tidak akan berfungsi, karena karakter no-op akan melakukan operasi yang salah. Saya menggunakannya dalam solusi 80 byte saya sebelumnya.
ETHproduk
Bukankah panah lemak ES6 standar pada PPCG yang harus Anda tetapkan?
MayorMonty
@SpeedyNinja Saya tidak tahu standar seperti itu, tetapi jika Anda bisa mengarahkan saya ke posting tentang satu, saya akan mengubah jawaban saya.
ETHproduksi
8

CJam, 37 byte

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

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

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
sumber
8

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

Wow, ini sudah banyak golf! Terima kasih kepada semua orang yang memberi saya saran! Saya sangat menghargainya!

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

Golfed 31 (!) Byte dengan mengoptimalkan nibble swap dengan operasi bitwise sebagai lawan dari Integer.???metode yang panjang .

Golfed 72 (!!!!) chars dengan menghapus string yang tidak perlu dibuat untuk menukar camilan. Jauh lebih baik dari sebelumnya !?

Golfed 45 (!!) karakter dengan menghapus penggunaan java.util.Scannerdan membaca System.inlangsung. Perhatikan bahwa sekarang karena ekspresi lambda hilang, Java 8 tidak lagi diperlukan! Hanya dengan Java 1 saja!

Golf 7 karakter dengan membuat kelas (default)( publickata kunci dihapus ), terima kasih kepada @bmarks

Golf 120 (!!!!!!!) karakter dengan memutar semua Integeroperasi kelas yang panjang dalam sedikit membalik 255 - a. Nah, itu jauh lebih singkat!

Golf 15 (!) Karakter dengan mengubah shift ke perkalian dan pembagian, menghapus kawat gigi dari pernyataan while, dan membuat alokal dalam mainmetode.

Ungolfed 9 = (karakter karena masalah dengan shift kiri tidak membuang byte paling kiri. Oleh karena itu, sekarang saya lakukan mod (256). Shift kanan akan membuat nomor yang dihasilkan sedikit lebih pendek dari sebelumnya, sehingga tidak perlu digunakan modpada shift kanan. Nibble-swap saya akan menukar 4 bit terakhir dan nibble kedua terakhir, dan and (&)memotong semua bit lainnya. Program inversi saya tidak menimbulkan masalah jika nomor aslinya kurang dari 256.

Golf 31 35 karakter berkat @Geobits dengan mengubah switchpernyataan menjadi banyak pernyataan ternary, dan juga mengubah karakter menjadi int, memperpendek literal.

Golf 7 karakter dengan menghapus yang tidak perlu &240di swap menggigit ( (a&240)>>4ke a>>4dan mengkonversi (a&15)<<4ke a<<4&240. Perubahan terakhir hanya golf satu karakter.

Golfed 1 arang dengan menghapus yang tidak perlu =di a /= 2, karena a = a /= 2setara dengan a = a / 2.

Golf 2 karakter dengan beralih printlnke print.

Golf 2 karakter dengan menghapus disengaja a=dalam a=255-a( a=a=255-asetara dengan a=255-a)

Golf 1 char dengan berubah a<<4&240menjadi a%16<<4.

Golf 1 char dengan menambahkan tanda kurung ke luar pernyataan ternary dan melakukan %256. Dengan begitu, %16tidak perlu di bagian shift-kiri dari nibble swap. Kurung menambahkan 2 karakter dan %16menyimpan 3 karakter.

Golf 3 karakter dengan mengubah classke interfacedan menghapus publicmenggunakan fitur metode antarmuka statis Java 8. Terima kasih kepada @TheNumberOne (tidak ada komentar, tetapi temukan jawabannya di "Tips untuk bermain golf di Jawa"

HyperNeutrino
sumber
Saya tidak berpikir bahwa kelas harus bersifat publik. Juga, saya pikir jika Anda membuat Integer alih-alih int, Anda bisa melakukan a.parseInt, a.toString, dll. Bukannya Integer.parseInt, Integer.toString, dll.
spanduk
Terima kasih atas saran pertama; Saya akan menghapus semua Integermetode kelas.
HyperNeutrino
Mungkin Anda bisa melakukan while ((i = System.in.read ())> 10) alih-alih! = 10 untuk menyimpan byte?
penanda
Gagasan bagus, tapi kemudian apa pun di bawah 10 akan menyebabkan program berakhir, dan saya seharusnya mengabaikan karakter lain, tidak menjadikan akhir dunia (atau setidaknya program saya :)) Saya akan mempertimbangkannya; mungkin tidak ada karakter ascii yang valid di bawah 10.
HyperNeutrino
4
Ini hampir tidak pernah layak untuk menggunakan switchgolf sementara. The case/ breakyang terlalu panjang. Anda harus bisa menyelamatkan banyak dengan membuat semuanya menjadi ternary; sesuatu sepertia=i=='!'?255-a:i==62?a/2:i=='<'?a*2%256:i=='@'?(a&240)>>4|(a&15)<<4:a;
Geobits
7

Rust, 121 115 byte

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}

Contoh dijalankan:

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

Tidak Disatukan:

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
}

Sangat pendek untuk Rust. Tidak ada hal lain yang benar-benar menarik selain fakta bahwa saya belajar lebih banyak aturan diutamakan hari ini — yang tahu (a>>b)|csama a>>b|c?

Memotong satu byte dengan mengubah n>>=1ke n/=2; Namun, hal yang sama tidak dapat dilakukan dengan perkalian, karena aritmatika overflow adalah kepanikan (yaitu crash) di Rust.

Gagang pintu
sumber
2
Didahulukan hal masuk akal ketika Anda meyakinkan diri sendiri bahwa >>adalah semacam seperti divisi dan |merupakan semacam seperti penambahan.
Lynn
6

HP 41C / CV / CX (? Byte, 42 langkah)

Murni untuk cekikikan, ini dia kalkulator HP 41C / CV / CX. (Membutuhkan modul Fungsi Diperluas, atau 41CX untuk fungsi ATOX.) Sayangnya, kalkulator tidak melaporkan ukuran program dalam byte.

Masukkan program Anda ke dalam register Alpha, yang sedikit rumit, karena tidak ada cara untuk masuk! atau @ langsung dari keyboard (gunakan XTOA masing-masing dengan kode ASCII 33 dan 64 untuk menambahkannya).

Langkah 08 dan 10 memungkinkan untuk mengabaikan opcode yang tidak valid; hapus langkah-langkah itu untuk menyimpan 2 langkah, tetapi program akan macet pada input yang tidak valid.

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
sumber
6

Python 2, 79 byte

Saya menyadari bahwa saya telah melakukan sesuatu yang sangat mirip dengan ini di Python sebelumnya. Ini hanyalah port jawaban Ruby saya , tetapi kebetulan itu adalah jawaban Python terpendek seperti sekarang: D

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

Perbedaan dari versi Ruby adalah bahwa ini tidak mengabaikan instruksi yang tidak valid saat iterasi input. Alih-alih, saya mengambil keuntungan dari fakta bahwa Python cenderung untuk kembali -1alih-alih nilketika tidak ada kecocokan - Nilai saat aini ditambahkan ke bagian belakang array hasil, sehingga semua instruksi yang tidak valid memetakan ke nilai yang sama dan tidak berubah.

daniero
sumber
4

Python 3, 124 94 93 byte

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)

"!" sama dengan mengurangi dari 255.
"<" sama dengan mengalikan dengan 2. Tetapi register 8 bit berarti mod 256.
">" sama dengan pembagian integer dengan 2.
"@" berarti menggeser 4 bit terakhir ( a%16) dengan 4 bit ( *16) dan menambahkan empat bit pertama ( a/16).

EDIT (baca penyalinan memalukan)
Melihat jawaban lain dengan python (dengan peluruhan Beta). Ini menggunakan cara yang sangat efektif untuk mensimulasikan kasus saklar menggunakan kamus. Dengan itu kita bisa menulis

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

Terima kasih, Beta Decay.

Rohcana
sumber
Tidak peduli apa operasi yang Anda lakukan, Anda harus mengurangi mod 256kan? Jadi mengapa tidak melakukan itu di akhir: a={"!":255-a,"<":a*2,">":a//2,"@":(a%16)<<4+a>>4}.get(i,a)%256. Ini segera menghemat satu byte (karena Anda akan melakukan a*2alih - alih a<<1) ... tetapi jawaban @ daniero juga menunjukkan bahwa jika Anda melakukannya dengan cara ini maka (a%16)<<4dapat disingkat menjadi hanya a<<4, karena bit 16 atau lebih besar akan dihilangkan setelah Anda mengalikan dengan 16 dan menguranginya mod 256. Bagus! Selain itu, Anda sekarang dapat mengganti 255-adengan -1-a... atau lebih baik, hanya dengan ~a. Secara keseluruhan, saran ini akan menghemat 9 byte.
mathmandan
3

Haskell, 89 byte

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

Contoh penggunaan: f "!>>"->63

nimi
sumber
3

Rust, 111 byte

Lebih banyak komentar pada jawaban @ Doorknob, tapi saya tidak punya perwakilan untuk komentar karena saya baru saja membuat akun.

Satu dapat mencukur 10 byte dari solusi Rust-nya dengan berikut:

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}
pengguna4867444
sumber
Saya pikir kami bisa lebih pendek menggunakan flip ( doc.rust-lang.org/std/iter/trait.Iterator.html#method.fold ) tetapi secara mengejutkan membuatnya sedikit lebih lama.
user4867444
3

Python 3, 127 byte

Edit: korslet, terima kasih @ Jakube

Sunting2: perbaiki, terima kasih @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
sumber
Mungkin ini karena baris baru windows. Itu ditambah dua byte. Saya akan menggunakan penghitung byte lain kali. :-) Terima kasih.
uno20001
Perhatikan bahwa ini tidak membuang bit paling kiri saat bergeser, jadi !<berikan 510waktu yang seharusnya254
Rohcana
Saya harap sekarang bisa. Maaf atas kesalahan saya, ini adalah tantangan "golf" pertama saya.
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);}

Diformat:

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

#fdan #f0merupakan bilangan heksadesimal untuk camilan, .bytemengubah integer menjadi byte. Saya beruntung bahwa .stringatribut Byte sudah menggunakan representasi byte yang tidak ditandatangani. Ceylon juga memiliki fitur pernyataan switch tanpa jatuh, dan string adalah daftar karakter, yang dapat diulang.

Saya juga mencoba untuk memotong nama-nama metode shift panjang dengan menggunakan impor aliasing, tetapi ini sebenarnya menjadi 7 byte lebih lama:

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

Diformat:

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

Ini mungkin berguna jika kita membutuhkan metode itu sedikit lebih sering.

Paŭlo Ebermann
sumber
3

Rubi, 81 73 byte

Jauh lebih sederhana - tanpa eval! Untuk setiap karakter yang valid dalam input, ia mengevaluasi setiap instruksi, dan menemukan instruksi yang sesuai melalui indeks $&(karakter saat ini dalam input).

a=0
gets.scan(/[!><@]/){a=[~a,a/2,a*2,a*16+a/16]["!><@".index$&]&255}
p a
daniero
sumber
1
Itu jenius. Jauh lebih pendek dengan cara lain. 2 positif oleh saya!
edc65
Bagaimana Anda bisa menggandakan upvote ...?
HyperNeutrino
@ JamesSmith Dia mungkin merujuk pada ini dan jawaban python saya :)
daniero
@danerio, begitu.
HyperNeutrino
2

STATA, 197 byte

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

Tidak disatukan

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

Tidak bekerja dengan penerjemah online dan memerlukan penerjemah default tidak bebas. Ini akan lebih mudah dengan operasi bitwise yang sebenarnya, tetapi saya tidak berpikir mereka terlalu berguna untuk sebagian besar penggunaan umum STATA.

tanda
sumber
Mengapa interpreter online tidak berfungsi?
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)

Operator ternary memetakan instruksi.

BITWISE AND digunakan untuk membatasi tipe Number kami menjadi satu byte.

Andrew Vermie
sumber
2

Julia, 117 94 86 73 byte

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)

Ini adalah fungsi anonim yang menerima string dan mengembalikan integer. Untuk menyebutnya, tetapkan ke variabel.

Tidak Disatukan:

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

Disimpan 8 byte berkat Sp3000 dan 13 berkat Dennis!

Alex A.
sumber
2

JavaScript (ES6), 76 81

Sebagai fungsi yang tidak disebutkan namanya mengembalikan nilai akumulator

Ini adalah porting jawaban super pintar oleh @daniero (yang memiliki terlalu sedikit upvotes)

Bonus: Anda dapat melewati nilai awal akumulator. Jika tidak lulus, nilai awal adalah 0 sebagai spesifik.

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

Tes menjalankan cuplikan di bawah ini di peramban EcmaScript 6 apa pun (saya uji di 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
sumber
1

Crystal, 139 byte

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
sumber
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
sumber
2
Apakah Anda tidak perlu using System;atau sesuatu seperti itu untuk mengakses Console.ReadLinedan Console.Writetanpa System.awalan?
Alex A.
Juga bagi saya sepertinya Anda tidak perlu melakukan cast byteuntuk setiap operasi tetapi saya bisa saja salah.
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))

Terinspirasi oleh @Beta Decay menggunakan akumulator string, mengingat lua tidak memiliki tipe byte. Mungkin bisa bermain golf lebih banyak dengan menggunakan lebih sedikit fungsi.

Delya Erricson
sumber
1

R, 194 byte

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))))
mawir
sumber
Semua itu <-bisa diganti di =sini, sehingga mengurangi kode sebanyak 7 byte. Selain itu, Anda mungkin dapat mengganti serangkaian ifpernyataan dengan satu panggilan ke switch(seperti pada A=switch(r,"!"=(A+1)%%2, ...))
plannapus
Hasilnya 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))))adalah 167 byte.
plannapus
1

RPL, 170,5 byte

Input harus dimasukkan sebagai string pada level 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
sumber
1

K, 57 byte

Ini awal:

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

diuji menggunakan 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

Saya mungkin bisa melakukan yang lebih baik di k5, tapi ini adalah serangkaian kompromi yang rumit - misalnya, mengubah biner ke desimal semudah 2/, tetapi perilaku ?membuatnya lebih sulit untuk menangani kasus default untuk pencarian instruksi.

JohnE
sumber
1

PHP, 189 byte

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

Bukannya itu akan mengalahkan banyak jawaban, itu hanya untuk latihan

Einacio
sumber
1

HPPPL , 302 294 byte

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

Tidak Disatukan:

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

Perintah Input HPPPL

Output HPPPL ke Terminal

Jawaban ini memastikan bahwa HP Prime menggunakan bilangan bulat 8 bit yang tidak ditandatangani meskipun mode diatur ke misalnya 64 bit oleh pengguna. Jika kalkulator diatur secara manual untuk menggunakan bilangan bulat desimal 8 bit yang tidak ditandatangani, maka pragmaperintah dapat dihilangkan. Jika output tidak perlu mengikuti format ketat maka a*1pada akhirnya bisa dengan mudah a. Mengalikan hasilnya dengan 1 hanya memastikan output tidak mengikuti output internal untuk nilai integer. The printperintah di baris 4 juga dapat dihilangkan jika terminal tidak perlu dibersihkan sebelum mencetak hasilnya. Jika melewati program sebagai argumen string diizinkan, maka INPUTperintah dapat dihilangkan juga.

Ini adalah versi terpendek dengan input dan output yang tepat, tanpa argumen pragma (jika kalkulator diatur ke Uint8 secara default:

243 byte:

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
sumber
1

Perl 6, 96 89 byte

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

Solusi lama:

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

C #, 119 byte

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

Versi lain saya coba, tetapi membutuhkan lebih banyak byte:

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
sumber
1

Python 2.7.3, 104 byte

Memiliki kode dalam string untuk dievaluasi terlihat sangat kotor, tetapi berfungsi: 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

Inilah output (dan input sebenarnya ..)

Dan ya, itu benar-benar berjalan pada RaspberryPi :)

Contoh output

Stefan
sumber