Програмування з бітами та байтами


40

У цьому виклику ви збираєтесь написати перекладача простою мовою, яку я склав. Мова ґрунтується на одному акумуляторі A, який дорівнює рівно одному байту. На початку програми A = 0. Це мовні інструкції:

!: Інверсія

Ця інструкція просто перевертає кожен шматочок акумулятора. Кожен нуль стає єдиним і кожен стає нулем. Просто!

>: Зсув праворуч

Ця інструкція зміщується кожен біт на A в одному місці вправо. Кращий лівий біт стає нулем, а правий біт відкидається.

<: Зсув вліво

Ця інструкція зміщується кожен біт на A в одному місці вліво. Крайній правий біт стає нулем, а лівий біт відкидається.

@: Поміняйте Nybbles

Ця інструкція замінює чотири верхніх біта A на чотири нижніх біта. Наприклад, якщо A є, 01101010а ви виконаєте @, A буде 10100110:

 ____________________
 |                  |
0110 1010    1010 0110
      |_______|

Ось і всі інструкції! Просте, правда?

Правила

  • Ваша програма повинна прийняти введення один раз на початку. Це буде рядок коду. Це не інтерактивний перекладач! Ви можете прийняти введення лише один раз, і не потрібно повертати його до початку, як тільки цей рядок буде виконаний.
  • Ваша програма повинна оцінити вказаний вклад. Кожен символ, який не згадується вище, ігнорується.
  • Тоді ваша програма повинна роздрукувати остаточне значення акумулятора, у десятковій частині.
  • Застосовуються звичайні правила для дійсних мов програмування.
  • Стандартні лазівки заборонені.
  • Це , найменший виграш у кількості байтів.

Ось кілька невеликих програм для перевірки ваших заявок. Перед стрілкою є код, після нього очікуваний результат:

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

Насолоджуйтесь!


Я припускаю, ! -> 255що ми тут використовуватимемо 8 біт на байт? Питання не є явним.
Toby Speight

3
@TobySpeight Байт, за визначенням, становить 8 біт.
HyperNeutrino

Відповіді:


15

Pyth, 36 35 байт

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

Тестовий джгут

Внутрішнє представлення акумулятора - ціле число. Це число модифікується по 256 на кожній ітерації, як бажано. Операції , що виконуються в -G-1, G/2, G*2та Gперетворюються в базу 16, звернені, і перетворяться назад до основи 10, де Gзнаходиться акумулятор.

Я пропустив лінію про ігнорування всього іншого. Це було виправлено. Дякую, @Dennis.


Так -G-1коротше, ніж ~Gу Pyth? Я дещо сумніваюся в цьому.
CalculatorFeline

Код, про який йде мова, насправді t_G, де _заперечення і tє -1. У Pyth ~означає щось зовсім інше.
isaacg

Я мав на увазі Python ~(побіжно НЕ)
CalculatorFeline

@CalculatorFeline Моя думка полягала в тому, що в Pyth немає жодної символьної функції з таким ефектом, тому наведений вище код (принаймні для цієї операції) такий же хороший, як і збирається отримати.
isaacg

13

С, 96

Припускаючи вхід ASCII (або сумісний):

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

В основному це лише сукупність вкладених потрійних виразів. Я збільшую значення, отримане з getchar()того, що EOF (-1) призводить до значення нуля, а програма закінчується.

(посилання ideone)


1
Я сам спробував виклик і написав майже такий самий код. Btw. ваша програма не скидає біт під час зміщення вгору (введення: !<>повинно призвести до, 127а не 255). Або визначте свій aяк char, або використовуйте рядок a&=255(і використовуйте %u), щоб отримати правильний ефект. Також ви можете скоротити своє заперечення a^255до ~a. a>>4&15також коротше вашого (a&240)/16.
MarcDefiant

Ах, хороший пункт. Виявляється, було ефективніше маскувати нижні 8 біт при кожній ітерації.
писклива косточка

1
У цьому випадку ви можете навіть використовувати рядок формату %uзамість%hhu
MarcDefiant

1
Я щойно бачив це, але ви також можете використовувати a/16|a*16замість цього a/16|(a&15)*16. Кілька біт зверху видаляються &255.
MarcDefiant

1
Невелике покращення: a*257/16на один байт коротше, ніж a/16|a*16.
Toby Speight

11

Python 3, 133 байти

Використовує словник, щоб компенсувати відсутність синтаксису регістру комутаторів у Python. Додаткову інформацію дивіться тут .

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

Акумулятор - це рядок, який в кінці перетворюється на базове число 10.

Приклад вводу / виводу:

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

Якби це був справжній інтерактивний перекладач, це було б for i in sys.stdin::)
Zizouz212

4
@ Zizouz212 Я вважаю, ти маєш на увазі, якби це було інтерактивно; мені схоже на справжнього перекладача. ;)
Олексій А.

9

Javascript (ES6), 80 91 90 байт

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

Приблизно стільки ж короткого, скільки може отримати. Визначає анонімну функцію, яка приймає програму як вхід.

  • Бо !, вважає x XOR 255, як JS ~вважали xб 32-розрядне число.
  • Для <, множиться xна 2 і приймає результат мод 256.
  • Бо >по-справжньому зміщує біти x1 біта вправо.
  • Бо @, підлоги x/16і додає його x%16*16.

Дякуємо @vihan за пропозицію використання reduceдля збереження байта.


Ви можете використовувати <для збереження близько 4 байт. Використання скорочення також може зберегти кілька байт
Downgoat

1
@vihan Ви маєте на увазі <замість ==? Якщо це так, це не буде працювати, оскільки неоперативні символи неправильно виконали б операцію. Я використовував це у своєму попередньому 80-байтному рішенні.
ETHproductions

Чи не стандартна стрілка ES6 для PPCG, яку ви повинні визначити?
МерМонті

@SpeedyNinja Я не знаю жодного такого стандарту, але якщо ви зможете вказати мені на повідомлення про таке, я зміню свою відповідь.
ETHproductions

8

CJam, 37 байт

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

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Як це працює

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 символів

Нічого собі, це було багато в гольфі! Дякую всім, хто дав мені пропозиції! Я дуже ціную це!

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 (!) Байтів, що увійшли в гольф, оптимізувавши своп ніблів за допомогою побітових операцій на відміну від тривалих Integer.???методів.

Залишивши 72 символи (!!!!), видаливши непотрібну струну, створену для заміни примх. Набагато краще, ніж раніше !?

Завантажений 45 (!!) символами, видаляючи користування java.util.Scannerта читаючи System.inбезпосередньо. Зауважте, що тепер, коли лямбда-вираз зник, Java 8 більше не потрібна! Просто Java 1 зробить!

Отримавши 7 символів, створивши клас (default)(видалене publicключове слово), завдяки @bmarks

Полезний 120 (!!!!!!!) символів, перетворивши всі ці тривалі Integerоперації класу в біт, що перевертається 255 - a. Тепер це набагато коротше!

Гольф 15 (!) Символів шляхом перетворення зрушень на множення та ділення, вилучення дужок з оператора while і введення методу aлокально main.

Ungolfed 9 = (символи через те, що зсув лівої сторони не відкидає крайній лівий байт. Тому я зараз це роблю mod (256). Правий зсув зробить отримане число на один раз коротшим, ніж раніше, тому немає необхідності використовувати modпри правильному зрушенні. Моя річ-swap замінить останні 4 біти і другий-останній nibble, і and (&)обрізає всі інші біти. Моя програма інверсії не викликає проблем, якщо початкове число менше 256.

Golfed 31 35 символів завдяки @Geobits конвертуючи switchзаяву у велику кількість потрійних висловлювань, а також перетворює символи в ints, скорочуючи букви.

Отримавши 7 символів, видаливши непотрібне &240в своп- свопі ( (a&240)>>4до a>>4та переходячи (a&15)<<4до a<<4&240. Остання зміна лише одного персонажа в гольфі).

Golfed 1 напівкоксу шляхом видалення непотрібних =ін a /= 2, тому що a = a /= 2еквівалентно a = a / 2.

Повернувшись до 2-х символів, поворотів printlnна них print.

Оснащений двома знаками, видаливши випадково a=в a=255-a( a=a=255-aеквівалентно a=255-a)

Поле 1 гольф, перетворившись a<<4&240на a%16<<4.

Поле 1 гольф, додаючи дужки до зовнішньої сторони термінальної заяви і виконуючи це %256. Таким чином, %16у лівій змінній частині підкатки, що пересувається, ліворуч. У дужках додається 2 символи, а в %16економії - 3.

Golfed 3 символів шляхом зміни classдо interfaceі видалення з publicдопомогою функції методи статичного інтерфейсу Java 8 ст. Дякуємо @TheNumberOne (коментарів немає, але знайдіть його відповідь на тему "Поради щодо гольфу на Яві"


Я не думаю, що клас повинен бути публічним. Крім того, я думаю, що якщо ви зробите Integer замість int, ви можете зробити a.parseInt, a.toString тощо замість Integer.parseInt, Integer.toString тощо
позначки

Дякую за першу пропозицію; Я збираюся видалити всі Integerметоди класу.
HyperNeutrino

Можливо, ви можете зробити while ((i = System.in.read ())> 10) замість! = 10, щоб зберегти байт?
позначки

Гарна ідея, але тоді все, що нижче 10, призведе до припинення програми, і я повинен ігнорувати інших персонажів, а не робити тоді кінець світу (або, принаймні, мою програму :)) Я вважаю це, хоча; можливо, немає дійсних символів ascii нижче 10.
HyperNeutrino

4
Це ніколи майже ніколи не варто використовувати switchтой час як гра в гольф. case/ breakПросто занадто довго. Ви повинні бути в змозі зберегти купу, зробивши всю річ потрійною; щось на кшталтa=i=='!'?255-a:i==62?a/2:i=='<'?a*2%256:i=='@'?(a&240)>>4|(a&15)<<4:a;
Geobits

7

Іржа, 121 115 байт

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}

Проба зразка:

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

Безголовки:

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
}

Напрочуд короткий для Расті. Нічого іншого насправді цікавого, окрім того, що сьогодні я дізнався більше правил пріоритетності - хто знав (a>>b)|c, що таке a>>b|c?

Оббрив байт, змінивши n>>=1на n/=2; однак те ж саме не можна зробити з множенням, оскільки арифметичне переповнення - це паніка (тобто збій) у Русті.


2
Старшинство річ має сенс , коли ви переконаєте себе , що >>це свого роду походить ділення і |є свого роду походить доповнення.
Лінн

6

HP 41C / CV / CX (? Байт, 42 кроки)

Суто для хихикань, ось це для калькулятора HP 41C / CV / CX. (Потрібен або модуль розширених функцій, або 41CX для функції ATOX.) На жаль, калькулятор не повідомляє розміри програми в байтах.

Покладіть свою програму в реєстр Альфа, що трохи хитро, оскільки немає можливості ввійти! або @ безпосередньо з клавіатури (використовуйте XTOA з кодами ASCII 33 та 64 відповідно, щоб додати їх).

Кроки 08 та 10 дозволяють ігнорувати недійсні опкоди; видаліть їх, щоб зберегти 2 кроки, але програма вийде з ладу при неправильному введенні.

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 байт

Я зрозумів, що раніше робив щось дуже схоже на це в Python. Це лише портрет моєї відповіді Ruby , але це, до речі, найкоротша відповідь 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

Відмінність від версії Ruby полягає в тому, що ця не ігнорує недійсні інструкції під час ітерації над входом. Замість цього я скористатися тим , що Python має тенденцію повертатися -1замість nilколи немає матчу - поточне значення aдодається до задньої частини результуючого масиву, так що всі недійсні інструкції карти до того ж, без зміни вартості.


4

Python 3, 124 94 93 байт

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)

"!" - це те саме, що віднімання з 255.
"<" - це те саме, що множення на 2. Але 8-бітний регістр означає mod 256.
">" - це те саме, що ділиться цілим числом на 2.
"@" означає зміщення останніх 4 біт ( a%16) на 4 біти ( *16) і додавання перших чотирьох біт ( a/16).

EDIT (читати безсоромне копіювання)
Іншу відповідь побачив у python (за допомогою бета-розкладу). Він використовує дійсно ефективний спосіб імітувати перемикання справ за допомогою словника. Використовуючи це, ми можемо писати

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

Спасибі, бета-розпад.


Незалежно від того, яку операцію ви робите, вам доведеться зменшити мод 256правильно? Так чому б не зробити це в кінці: a={"!":255-a,"<":a*2,">":a//2,"@":(a%16)<<4+a>>4}.get(i,a)%256. Це відразу економить вам байт (тому що ви будете робити a*2замість a<<1) ... але відповідь @ daniero також показує, що якщо ви зробите це таким чином, то (a%16)<<4його можна скоротити до просто a<<4, тому що будь-який біт 16 або більше буде усунутий, коли ви помножите це на 16 і зменшити його мод 256. Приємно! Крім того, тепер ви можете замінити 255-aна -1-a... або краще, просто ~a. Загалом ці пропозиції мають заощадити 9 байт.
mathmandan

3

Haskell, 89 байт

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

Приклад використання: f "!>>"->63


3

Іржа, 111 байт

Більше коментарів до відповіді @ Doorknob, але я не маю жодної відповіді для коментарів, оскільки я тільки що створив обліковий запис.

Можна вирізати 10 байт з його розчину іржі за допомогою наступного:

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}

Я думав, що ми можемо отримати ще коротше, використовуючи складку ( doc.rust-lang.org/std/iter/ Портрет.Iterator.html#method.fold ), але на диво це робить її в три рази довше.
user4867444

3

Python 3, 127 байт

Редагувати: коротко, спасибі @Jakube

Edit2: виправити, дякую @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)

Можливо, це тому, що нова лінія Windows. Це плюс два байти. Я буду використовувати цей лічильник байтів наступного разу. :-) Спасибі.
uno20001

Зауважте, що це не відкидає крайній лівий біт при зсуві ліворуч, тому !<дає, 510поки має бути254
Rohcana

Я сподіваюся, що зараз це і є Вибачте за мої помилки, це мій перший виклик "гольфу".
uno20001

3

Цейлон, 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);}

Відформатовано:

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і #f0є шістнадцятковими числами для nibbles, .byteперетворює ціле число в байт. Мені пощастило, що в .stringатрибуті Byte вже використовується неподписане байт. На Цейлоні також є оператор перемикання без пропускання, а рядок - це список символів, який можна повторити.

Я також намагався скоротити ці назви методів довгої зміни, використовуючи імпорт з ім'ям, але це фактично стає на 7 байт довше:

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

Відформатовано:

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

Це може бути корисно, якщо нам потрібні ці методи трохи частіше.


3

Рубі, 81 73 байти

Настільки простіше - ніякого овалу! Для кожного дійсного символу на вході він оцінює кожну інструкцію та знаходить відповідну інструкцію через індекс $&(поточний символ у введенні).

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

1
Це геній. Набагато коротше, ніж будь-який інший спосіб. 2 оновлення мною!
edc65

Як можна подвійно оцінити ...?
HyperNeutrino

@JamesSmith Він, мабуть, має на увазі це та мою відповідь python :)
daniero

@danerio Я бачу.
HyperNeutrino

2

STATA, 197 байт

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

Безумовно

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

Не працює з онлайн-перекладачем і вимагає невільного перекладача за замовчуванням. Це було б дещо простіше з фактичними побітними операціями, але я не думаю, що вони занадто корисні для більшості поширених застосувань STATA.


Чому інтернет-перекладач не працює?
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)

Вкладені потрійні оператори відображають вказівки.

BITWISE AND використовується для обмеження нашого типу номера одним байтом.


2

Джулія, 117 94 86 73 байт

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)

Це анонімна функція, яка приймає рядок і повертає ціле число. Щоб викликати його, призначте його змінній.

Безголовки:

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 байт завдяки Sp3000 та 13 завдяки Деннісу!


2

JavaScript (ES6), 76 81

Як неназвана функція, що повертає значення акумулятора

Це надсилання супер розумних відповідей від @daniero (у яких занадто мало відгуків)

Бонус: ви можете передати початкове значення акумулятора. Якщо його не пропустити, початкове значення дорівнює 0 за конкретними показниками.

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

Тестуйте запуск фрагмента нижче в будь-якому веб-переглядачі EcmaScript 6 (я тестував у 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

Кристал, 139 байт

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
Вам не потрібно using System;чи щось подібне для доступу Console.ReadLineта Console.Writeбез System.префікса?
Олексій А.

Також мені здається, що вам не потрібно було б звертатися byteза кожною операцією, але я можу помилитися.
Олексій А.

1

Луа, 344 чал

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

Натхненний використанням @Beta Decay використання струнного акумулятора, бачачи, що луа не має байтового типу. Можливо, можна було б більше грати в гольф, використовуючи менше функцій.


1

R, 194 байт

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

неозорий

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

Все <-можна замінити =тут, таким чином , зменшуючи код на 7 байт. Крім того, ви можете бути в змозі замінити серію ifзаяв одним дзвінком на switch(як в A=switch(r,"!"=(A+1)%%2, ...))
планп

Отриманий результат 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))))- 167 байт.
планнапус

1

RPL, 170,5 байт

Вхід повинен бути введений як рядок на рівні 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

К, 57 байт

Це початок:

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

тестовано за допомогою 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

Я б міг зробити краще в k5, але це складна серія компромісів - наприклад, перетворення двійкового в десятковий так само просто 2/, але поведінка ?ускладнює обробку випадку за замовчуванням для пошуку інструкцій.


1

PHP, 189 байт

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

Справа не в тому, що вона переможе багато відповідей, це лише на практиці


1

HPPPL , 302 294 байт

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

Безголовки:

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

Вихід ГЕС на термінал

Ця відповідь гарантує, що HP Prime використовує непідписані 8-бітові цілі числа, навіть якщо для користувача встановлений режим, наприклад, 64 біти. Якщо калькулятор налаштовано вручну з використанням неподписаних 8-бітних десяткових цілих чисел, pragmaкоманду можна опустити. Якщо для виводу не потрібно чітко дотримуватися формату, то a*1в кінці може бути просто a. Помноження результату на 1 лише гарантує, що вихід не відповідає внутрішньому виводу для цілих значень. printКоманда в рядку 4 також може бути опущена , якщо термінал не повинен бути очищений перед друком з результату. Якщо передача програми в якості рядкового аргументу дозволена, INPUTкоманду можна також пропустити.

Це найкоротша версія з введенням та правильним висновком, без аргументу прагми (якщо для калькулятора за умовчанням встановлено Uint8:

243 байти:

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 байт

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

Старе рішення:

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

1

C #, 119 байт

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

Інші версії, які я спробував, але мені потрібно більше байтів:

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 байти

Маючи код у рядках, які оцінюються, виглядає досить брудно, але працює: 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

Ось вихід (і фактично введення ..)

І так, це дійсно працює на RaspberryPi :)

Приклад виведення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.