Lập trình với Bits và Byte


40

Trong thử thách này, bạn sẽ viết một thông dịch viên cho một ngôn ngữ đơn giản mà tôi đã tạo nên. Ngôn ngữ dựa trên một bộ tích lũy A, có độ dài chính xác một byte. Khi bắt đầu một chương trình, A = 0. Đây là các hướng dẫn ngôn ngữ:

!: Nghịch đảo

Hướng dẫn này chỉ đơn giản là đảo ngược mọi bit của bộ tích lũy. Mỗi số không trở thành một và mọi người trở thành số không. Đơn giản!

>: Chuyển sang phải

Hướng dẫn này dịch chuyển từng bit trong A một nơi sang phải. Bit ngoài cùng bên trái trở thành số 0 và bit ngoài cùng bên phải bị loại bỏ.

<: Sang trái

Hướng dẫn này dịch chuyển từng bit trong A một nơi sang trái. Bit ngoài cùng bên phải trở thành số 0 và bit ngoài cùng bên trái bị loại bỏ.

@: Hoán đổi Nybble

Hướng dẫn này hoán đổi bốn bit trên cùng của A với bốn bit dưới cùng. Ví dụ: Nếu A là 01101010và bạn thực thi @, A sẽ là 10100110:

 ____________________
 |                  |
0110 1010    1010 0110
      |_______|

Đó là tất cả các hướng dẫn! Đơn giản phải không?

Quy tắc

  • Chương trình của bạn phải chấp nhận đầu vào một lần khi bắt đầu. Đây sẽ là một dòng mã. Đây không phải là một thông dịch viên tương tác! Bạn chỉ có thể chấp nhận đầu vào một lần và không phải lặp lại từ đầu khi dòng đó đã được thực thi.
  • Chương trình của bạn phải đánh giá đầu vào nói. Mỗi nhân vật không được đề cập ở trên được bỏ qua.
  • Chương trình của bạn sau đó sẽ in ra giá trị cuối cùng của bộ tích lũy, theo số thập phân.
  • Quy tắc thông thường cho các ngôn ngữ lập trình hợp lệ được áp dụng.
  • Sơ hở tiêu chuẩn là không được phép.
  • Đây là , số byte nhỏ nhất sẽ thắng.

Dưới đây là một số chương trình nhỏ để kiểm tra bài nộp của bạn. Trước mũi tên là mã, sau đó là kết quả mong đợi:

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

Thưởng thức!


Tôi ! -> 255đoán rằng chúng ta sẽ sử dụng 8 bit cho mỗi byte ở đây? Câu hỏi không rõ ràng.
Toby Speight

3
@TobySpeight Một byte, theo định nghĩa, là 8 bit.
HyperNeutrino

Câu trả lời:


15

Bình thường, 36 35 byte

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

Khai thác thử nghiệm

Biểu diễn bên trong của bộ tích là một số nguyên. Số nguyên này được sửa đổi bởi 256 trên mỗi lần lặp, như mong muốn. Các hoạt động thực hiện được -G-1, G/2, G*2Gchuyển đổi sang cơ sở 16, đảo ngược, và lại chuyển đổi sang cơ sở 10, nơi Glà accumulator.

Tôi đã bỏ lỡ dòng về việc bỏ qua mọi thứ khác. Điều này đã được khắc phục. Cảm ơn, @Dennis.


Vậy -G-1là ngắn hơn ~Gở Pyth? Tôi hơi nghi ngờ điều đó.
Máy

Các mã trong câu hỏi thực sự là t_G, nơi _là phủ định và t-1. Trong Pyth, ~có nghĩa là một cái gì đó hoàn toàn khác nhau.
isaacg

Ý tôi là Python ~(bitwise KHÔNG)
CalculatorFeline

@CalculatorFeline Quan điểm của tôi là không có chức năng 1 ký tự với hiệu ứng đó trong Pyth, vì vậy đoạn mã trên (ít nhất là cho thao tác đó) cũng tốt như nó sẽ có.
isaacg

13

C, 96

Giả sử đầu vào ASCII (hoặc tương thích):

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

Về cơ bản nó chỉ là một bộ sưu tập các biểu thức chim nhạn lồng nhau. Tôi đang tăng giá trị thu được từ getchar()đó để EOF (-1) dẫn đến giá trị bằng 0 và chương trình thoát.

(liên kết ideone)


1
Tôi đã thử thách bản thân và tôi đã viết gần như chính xác cùng một mã. Btw. chương trình của bạn không giảm bit khi dịch chuyển lên trên (đầu vào: !<>nên dẫn đến 127và không 255). Hoặc xác định aas của bạn char, hoặc sử dụng dòng a&=255(và sử dụng %u) để có được hiệu ứng chính xác. Ngoài ra, bạn có thể rút ngắn phủ định của bạn a^255để ~a. a>>4&15cũng ngắn hơn của bạn (a&240)/16.
MarcDefiant

Ah, điểm tốt. Hóa ra nó hiệu quả hơn khi che dấu 8 bit thấp hơn ở mỗi lần lặp.
squossish ossifrage

1
Trong trường hợp này, bạn thậm chí có thể sử dụng chuỗi định dạng %uthay vì%hhu
MarcDefiant

1
Tôi chỉ thấy nó bây giờ, nhưng bạn cũng có thể sử dụng a/16|a*16thay vì a/16|(a&15)*16. Một vài bit trên đầu được loại bỏ bởi &255.
MarcDefiant

1
Một cải tiến nhỏ: a*257/16ngắn hơn một byte a/16|a*16.
Toby Speight

11

Python 3, 133 byte

Sử dụng một từ điển để bù cho thiếu cú ​​pháp trường hợp chuyển đổi trong Python. Xem thêm tại đây .

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

Bộ tích lũy là một chuỗi được chuyển đổi thành số 10 cơ sở ở cuối.

Ví dụ I / O:

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

Nếu đó là một trình thông dịch tương tác thực sự, nó sẽ là for i in sys.stdin::)
Zizouz212

4
@ Zizouz212 Tôi tin bạn có nghĩa là nếu nó tương tác; nó trông giống như một thông dịch viên thực sự với tôi ;)
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)

Khá ngắn như nó có thể nhận được. Xác định một hàm ẩn danh lấy chương trình làm đầu vào.

  • Đối với !, mất x XOR 255, vì JS ~sẽ xem xét xmột số 32 bit.
  • Cho <, nhân với x2 và lấy kết quả mod 256.
  • Đối với >, thực sự dịch chuyển các bit x1 bit sang phải.
  • Đối với @, sàn x/16và thêm nó vào x%16*16.

Cảm ơn @vihan đã đề xuất sử dụng reduceđể lưu một byte.


Bạn có thể sử dụng <để lưu khoảng 4 byte. Sử dụng giảm cũng có thể tiết kiệm một số byte
Downgoat

1
@vihan Ý bạn là <ở chỗ ==nào? Nếu vậy, điều đó sẽ không hoạt động, vì các nhân vật không hoạt động sẽ thực hiện một thao tác không chính xác. Tôi đã sử dụng nó trong giải pháp 80 byte trước đây của tôi.
Sản xuất ETH

Không phải là tiêu chuẩn mũi tên chất béo ES6 trên PPCG mà bạn phải xác định nó?
MayorMonty

@SpeedyNinja Tôi không biết bất kỳ tiêu chuẩn nào như vậy, nhưng nếu bạn có thể chỉ cho tôi một bài viết về một bài, tôi sẽ sửa đổi câu trả lời của tôi.
Sản phẩm ETH

8

CJam, 37 byte

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

Hãy thử trực tuyến trong trình thông dịch CJam .

Làm thế nào nó hoạt động

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 ký tự

Wow, điều này đã được đánh xuống rất nhiều! Cảm ơn tất cả những người đã cho tôi đề nghị! Tôi đánh giá rất cao nó!

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 bằng cách tối ưu hóa trao đổi nibble với các hoạt động bitwise trái ngược với Integer.???các phương thức dài .

Golf chars 72 (!!!!) bằng cách loại bỏ chuỗi không cần thiết được tạo để hoán đổi nibble. Tốt hơn nhiều so với trước đây!?

Đánh gôn 45 (!!) bằng cách loại bỏ việc sử dụng java.util.Scannervà đọc System.intrực tiếp. Lưu ý rằng bây giờ biểu thức lambda đã biến mất, Java 8 không còn cần thiết nữa! Chỉ cần Java 1 sẽ làm!

Đánh gôn 7 ký tự bằng cách tạo lớp (default)(loại bỏ publictừ khóa), nhờ @bmark

Đánh gôn 120 (!!!!!!!) bằng cách chuyển tất cả các Integerhoạt động lớp dài đó trong bit sang 255 - a. Bây giờ thì ngắn hơn nhiều!

Đánh dấu 15 ký tự (!) Bằng cách chuyển đổi ca sang phép nhân và chia, loại bỏ dấu ngoặc trong câu lệnh while và tạo acục bộ trong mainphương thức.

Ungolfed 9 = (ký tự vì có vấn đề với dịch chuyển trái không loại bỏ byte ngoài cùng bên trái. Do đó, bây giờ tôi làm mod (256). Dịch chuyển bên phải sẽ làm cho số kết quả ngắn hơn một chút so với trước, do đó không cần sử dụng moddịch chuyển phải. Điều trao đổi nibble của tôi sẽ trao đổi 4 bit cuối cùng và nibble cuối cùng thứ hai và and (&)cắt ngắn tất cả các bit khác. Chương trình đảo ngược của tôi không gây ra bất kỳ vấn đề nào nếu số ban đầu nhỏ hơn 256.

Golfed 31 35 chars nhờ @Geobits bằng cách chuyển đổi switchtuyên bố rất nhiều báo cáo ternary, và cũng có thể chuyển đổi ký tự để ints, rút ngắn literals.

Đánh gôn 7 ký tự bằng cách loại bỏ không cần thiết &240trong trao đổi nibble ( (a&240)>>4sang a>>4và chuyển đổi (a&15)<<4thành a<<4&240. Thay đổi cuối cùng chỉ đánh gôn một nhân vật.

Golfed 1 char bằng cách loại bỏ không cần thiết =trong a /= 2, bởi vì a = a /= 2tương đương với a = a / 2.

Chơi golf 2 chars bằng cách chuyển printlnsang print.

Đánh gôn 2 ký tự bằng cách loại bỏ ngẫu nhiên a=trong a=255-a( a=a=255-atương đương với a=255-a)

Đánh gôn 1 char bằng cách biến a<<4&240thành a%16<<4.

Đánh gôn 1 char bằng cách thêm dấu ngoặc vào bên ngoài câu lệnh ternary và làm %256. Theo cách đó, %16không cần thiết trong phần dịch chuyển trái của trao đổi nibble. Dấu ngoặc thêm 2 ký tự và %16lưu 3 ký tự.

Golfed 3 ký tự bằng cách thay đổi classđể interfacevà loại bỏ publicsử dụng tính năng phương pháp giao diện tĩnh Java 8 của. Cảm ơn @TheNumberOne (không có bình luận, nhưng tìm câu trả lời của anh ấy về "Mẹo chơi gôn trong Java"


Tôi không nghĩ rằng lớp học phải được công khai. Ngoài ra, tôi nghĩ rằng nếu bạn tạo một Số nguyên thay vì int, bạn có thể thực hiện a.parseInt, a.toString, v.v. thay vì Integer.parseInt, Integer.toString, v.v.
đánh dấu

Cảm ơn lời đề nghị đầu tiên; Tôi sẽ loại bỏ tất cả các Integerphương thức lớp mặc dù.
HyperNeutrino

Có lẽ bạn có thể làm while ((i = System.in.read ())> 10) thay vì! = 10 để lưu một byte?
đánh dấu

Ý tưởng hay, nhưng sau đó, bất cứ điều gì dưới 10 sẽ khiến chương trình chấm dứt, và tôi phải bỏ qua các nhân vật khác, không phải là ngày tận thế (hoặc ít nhất là chương trình của tôi :)) Tôi sẽ xem xét nó; có lẽ không có ký tự ascii hợp lệ nào dưới 10.
HyperNeutrino

4
gần như không bao giờ đáng để sử dụng switchtrong khi chơi golf. Các case/ breakchỉ là quá dài. Bạn sẽ có thể tiết kiệm một bó bằng cách làm cho toàn bộ điều trở thành một ternary; đại loại nhưa=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}

Chạy mẫu:

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

Ung dung:

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
}

Đáng ngạc nhiên là viết tắt của Rust. Không có gì khác thực sự thú vị khác với thực tế là tôi đã học quy tắc ưu tiên hơn ngày hôm nay -ai biết (a>>b)|ccũng giống như a>>b|c?

Cạo sạch một byte bằng cách thay đổi n>>=1thành n/=2; tuy nhiên, điều tương tự không thể được thực hiện với phép nhân, bởi vì tràn số học là một sự hoảng loạn (tức là sự cố) trong Rust.


2
Điều ưu tiên có ý nghĩa khi bạn thuyết phục bản thân đó >>loại giống như phân chia và |loại giống như bổ sung.
Lynn

6

HP 41C / CV / CX (? Byte, 42 bước)

Hoàn toàn cho tiếng cười khúc khích, ở đây nó dành cho máy tính HP 41C / CV / CX. (Không may, yêu cầu mô-đun Hàm mở rộng hoặc 41CX cho chức năng ATOX.) Thật không may, máy tính không báo cáo kích thước chương trình theo byte.

Đưa chương trình của bạn vào thanh ghi Alpha, điều này hơi khó, vì không có cách nào để vào! hoặc @ trực tiếp từ bàn phím (sử dụng XTOA với mã ASCII lần lượt là 33 và 64 để nối thêm chúng).

Bước 08 và 10 cho phép bỏ qua các opcode không hợp lệ; xóa chúng để lưu 2 bước, nhưng chương trình sẽ bị sập khi nhập không hợp lệ.

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 byte

Tôi nhận ra rằng tôi đã làm một cái gì đó rất giống với điều này trong Python trước đó. Đây chỉ là một cổng trong câu trả lời Ruby của tôi , nhưng đây là câu trả lời Python ngắn nhất hiện tại: D

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

Sự khác biệt so với phiên bản Ruby là phiên bản này không bỏ qua các hướng dẫn không hợp lệ trong khi lặp lại đầu vào. Thay vào đó, tôi tận dụng thực tế là Python có xu hướng quay trở lại -1thay vì nilkhi không có kết quả khớp - Giá trị hiện tại của ađược gắn vào mặt sau của mảng kết quả, để tất cả các hướng dẫn không hợp lệ ánh xạ tới cùng một giá trị không đổi.


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)

"!" giống như trừ đi 255.
"<" giống như nhân với 2. Nhưng thanh ghi 8 bit có nghĩa là mod 256.
">" giống như phép chia số nguyên cho 2.
"@" có nghĩa là dịch chuyển 4 bit cuối ( a%16) bằng 4 bit () *16) và thêm bốn bit đầu tiên ( a/16).

EDIT (đọc bản sao không biết xấu hổ)
Thấy câu trả lời khác trong python (bằng cách phân rã Beta). Nó sử dụng một cách thực sự hiệu quả để mô phỏng các trường hợp chuyển đổi bằng từ điển. Sử dụng chúng ta có thể viết

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

Cảm ơn, phân rã Beta.


Không có vấn đề gì bạn làm, bạn phải giảm mod 256phải không? Vậy tại sao không làm điều đó ở cuối : a={"!":255-a,"<":a*2,">":a//2,"@":(a%16)<<4+a>>4}.get(i,a)%256. Điều này ngay lập tức giúp bạn tiết kiệm một byte (vì bạn sẽ làm a*2thay vì a<<1) ... nhưng câu trả lời của @ daniero cũng cho thấy rằng nếu bạn làm theo cách này thì (a%16)<<4có thể rút ngắn lại a<<4, bởi vì bất kỳ bit 16 hoặc lớn hơn sẽ bị loại bỏ khi bạn nhân lên nó giảm 16 và giảm mod 256. Hay đấy! Ngoài ra, bây giờ bạn có thể thay thế 255-abằng -1-a... hoặc tốt hơn, chỉ bằng ~a. Tổng cộng, những đề xuất này sẽ giúp bạn tiết kiệm 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

Ví dụ sử dụng: f "!>>"->63


3

Rust, 111 byte

Thêm nhận xét về câu trả lời của @ Doorknob, nhưng tôi không có bất kỳ đại diện nào cho nhận xét khi tôi vừa tạo tài khoản.

Người ta có thể cạo 10 byte khỏi giải pháp Rust của mình bằng cách sau:

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}

Tôi nghĩ rằng chúng ta thậm chí có thể rút ngắn hơn bằng cách sử dụng nếp gấp ( doc.rust-lang.org/std/iter/trait.Iterator.html#method. Fold ) nhưng đáng ngạc nhiên là làm cho nó dài hơn một chút.
dùng4867444

3

Python 3, 127 byte

Chỉnh sửa: shorting, cảm ơn @Jakube

Edit2: sửa, cảm ơn @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)

Có lẽ điều này là do dòng mới của windows. Đó là cộng hai byte. Tôi sẽ sử dụng bộ đếm byte đó vào lần tới. :-) Cảm ơn.
uno20001

Lưu ý rằng điều này không loại bỏ bit ngoài cùng bên trái khi dịch chuyển trái, vì vậy hãy !<đưa ra 510trong khi nó nên254
Rohcana

Tôi hy vọng bây giờ nó làm. Xin lỗi vì những sai lầm của tôi, đây là thử thách "đánh gôn" đầu tiên của tôi.
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);}

Định dạng:

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

#f#f0là các số thập lục phân cho các nibble, .bytechuyển đổi một số nguyên thành một byte. Tôi may mắn rằng .stringthuộc tính của Byte đã sử dụng biểu diễn không dấu của một byte. Ceylon cũng có một câu lệnh chuyển đổi mà không có thông qua, và một chuỗi là một danh sách các ký tự, có thể được lặp lại.

Tôi cũng đã cố gắng cắt giảm các tên phương thức dịch chuyển dài đó bằng cách sử dụng nhập khẩu bí danh, nhưng điều này thực sự trở nên dài hơn 7 byte:

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

Định dạng:

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

Điều này có thể hữu ích nếu chúng ta cần những phương pháp đó thường xuyên hơn một chút.


3

Hồng ngọc 81 73 byte

Rất đơn giản - không có eval! Đối với mỗi ký tự hợp lệ trong đầu vào, nó đánh giá từng lệnh và tìm lệnh phù hợp thông qua chỉ mục của $&(ký tự hiện tại trong đầu vào).

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

1
Đó là thiên tài. Ngắn hơn nhiều so với bất kỳ cách nào khác. 2 upvote của tôi!
edc65

Làm thế nào bạn có thể tăng gấp đôi upvote ...?
HyperNeutrino

@JamesSmith Có lẽ anh ấy đang đề cập đến câu trả lời này và câu trả lời về con trăn của tôi :)
daniero

@danerio Tôi thấy.
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

Bị đánh cắp

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

Không hoạt động với trình thông dịch trực tuyến và yêu cầu trình thông dịch mặc định không miễn phí. Điều này sẽ dễ dàng hơn với các thao tác bitwise thực tế, nhưng tôi không nghĩ rằng chúng quá hữu ích cho hầu hết các sử dụng phổ biến của STATA.


Tại sao trình thông dịch trực tuyến không hoạt động?
Máy

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)

Các nhà khai thác ternary lồng nhau để hướng dẫn.

BITWISE AND được sử dụng để giới hạn loại Số của chúng tôi thành một byte đơn.


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)

Đây là một hàm ẩn danh chấp nhận một chuỗi và trả về một số nguyên. Để gọi nó, gán nó cho một biến.

Ung dung:

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

Đã lưu 8 byte nhờ Sp3000 và 13 nhờ Dennis!


2

JavaScript (ES6), 76 81

Là một hàm không tên trả về giá trị tích lũy

Đây là một câu trả lời siêu thông minh của @daniero (có quá ít câu trả lời)

Tiền thưởng: bạn có thể vượt qua một giá trị ban đầu của bộ tích lũy. Nếu không được thông qua, giá trị bắt đầu là 0 như cụ thể.

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

Kiểm tra chạy đoạn mã dưới đây trong bất kỳ trình duyệt EcmaScript 6 nào (tôi đã thử nghiệm trên 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>


1

Pha lê, 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

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
Bạn không cần using System;hoặc một cái gì đó như thế để truy cập Console.ReadLineConsole.Writekhông có System.tiền tố?
Alex A.

Ngoài ra, đối với tôi, bạn không cần phải thực hiện bytecho mỗi thao tác nhưng tôi có thể sai.
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))

Lấy cảm hứng từ việc sử dụng bộ tích lũy chuỗi của @Beta Decay, xem như lua không có loại byte. Có lẽ có thể được chơi golf nhiều hơn bằng cách sử dụng ít chức năng hơn.


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

vô dụng

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

Tất cả <-có thể được thay thế bởi =ở đây, do đó giảm mã 7 byte. Ngoài ra, bạn có thể thay thế một loạt các ifcâu lệnh bằng một cuộc gọi đến switch(như trong A=switch(r,"!"=(A+1)%%2, ...))
plannapus

Kết quả 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))))là 167 byte.
plannapus

1

RPL, 170,5 byte

Đầu vào phải được nhập dưới dạng chuỗi trên cấp 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 \>> 
\>>

1

K, 57 byte

Đó là một sự khởi đầu:

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

đã thử nghiệm bằng 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

Tôi có thể có thể làm tốt hơn trong k5, nhưng đó là một loạt các sự đánh đổi phức tạp - ví dụ, chuyển đổi nhị phân thành thập phân cũng dễ như vậy 2/, nhưng hành vi ?khiến việc xử lý trường hợp mặc định để tra cứu hướng dẫn trở nên khó khăn hơn.


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

Không phải là nó sẽ đánh bại nhiều câu trả lời, nó chỉ dành cho thực hành


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;

Ung dung:

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

Lệnh nhập HPPPL

HPPPL xuất ra thiết bị đầu cuối

Câu trả lời này đảm bảo rằng HP Prime sử dụng số nguyên 8 bit không dấu ngay cả khi chế độ được đặt thành ví dụ 64 bit bởi người dùng. Nếu máy tính được thiết lập thủ công để sử dụng số nguyên thập phân 8 bit không dấu, thì pragmalệnh có thể được bỏ qua. Nếu đầu ra không cần phải tuân theo định dạng một cách nghiêm ngặt thì a*1cuối cùng có thể chỉ đơn giản là a. Nhân kết quả với 1 chỉ đảm bảo đầu ra không theo đầu ra bên trong cho các giá trị nguyên. Các printlệnh trong dòng 4 cũng có thể được bỏ qua nếu các thiết bị đầu cuối không cần phải được xóa trước khi in ra kết quả. Nếu truyền chương trình dưới dạng đối số chuỗi được cho phép, thì INPUTlệnh cũng có thể được bỏ qua.

Đây là phiên bản ngắn nhất có đầu vào và đầu ra phù hợp, không có đối số pragma (nếu máy tính được đặt thành Uint8 theo mặc định:

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;

1

Perl 6, 96 89 byte

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

Giải pháp cũ:

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

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

Các phiên bản khác tôi đã thử, nhưng cần nhiều byte hơn:

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 byte

Có mã trong chuỗi được đánh giá trông khá bẩn, nhưng hoạt động: 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

Đây là đầu ra (và đầu vào thực sự ..)

Và vâng, nó thực sự đang chạy trên RaspberryPi :)

Ví dụ đầu ra

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.