Проста програма для котів


84

Одне з найпоширеніших стандартних завдань (особливо при демонстрації езотеричних мов програмування) - реалізувати "котячу програму" : прочитайте всі STDIN та роздрукуйте її до STDOUT. Хоча ця назва іменована утилітою оболонки Unix, catвона, звичайно, набагато менш потужна, ніж реальна річ, яка зазвичай використовується для друку (і об'єднання) декількох файлів, прочитаних з диска.

Завдання

Вам слід написати повну програму, яка читає вміст стандартного вхідного потоку і записує їх дослівно до стандартного вихідного потоку. Якщо і тільки якщо ваша мова не підтримує стандартні потоки введення та / або виведення (як це розуміється на більшості мов), ви можете замість цього прийняти ці терміни для позначення їх найближчого еквівалента у вашій мові (наприклад, JavaScript promptта alert). Це єдині допустимі форми вводу / виводу, оскільки будь-який інший інтерфейс значною мірою змінить характер завдання та зробить відповіді набагато менш порівняльними.

Вихід повинен містити саме вхід і більше нічого . Єдиним винятком із цього правила є постійний вихід перекладача вашої мови, який неможливо придушити, наприклад привітання, кольорові коди ANSI або відступ. Це стосується і останніх рядків. Якщо вхід не містить зворотного нового рядка, вихід також не повинен містити його! (Єдиним винятком є ​​те, якщо ваша мова абсолютно завжди друкує останній рядок після виконання.)

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

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

  • Якщо у вашій мові взагалі можливо відрізнити нульові байти у стандартному потоці введення від EOF, ваша програма повинна підтримувати нульові байти, як і будь-які інші байти (тобто вони також повинні бути записані в стандартний вихідний потік).
  • Якщо у вашій мові взагалі можливо підтримувати довільний нескінченний потік введення (тобто якщо ви можете розпочати друк байтів до виводу, перш ніж натиснути на EOF на вході), програма повинна в цьому випадку правильно працювати. Як приклад yes | tr -d \\n | ./my_catслід надрукувати нескінченний потік ys. Від вас залежить, як часто ви друкуєте та обмітаєте стандартний вихідний потік, але це повинно бути гарантовано, що це відбудеться через обмежений час, незалежно від потоку (зокрема, це означає, що ви не можете чекати конкретного символу, наприклад подача ліній перед друком).

Будь ласка, додайте примітку до вашої відповіді про точну поведінку щодо нульових байтів, нескінченних потоків та стороннього виводу.

Додаткові правила

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

  • Подання на більшості мов будуть оцінюватися в байтах у відповідному попередньому кодуванні, як правило (але не обов'язково) UTF-8.

    Деякі мови, як-от папки , досить складно оцінити. Якщо ви сумніваєтесь, будь ласка, запитайте про Meta .

  • Не соромтеся використовувати мову (або мовну версію), навіть якщо вона новіша, ніж ця проблема. Мови, спеціально написані для подання 0-байтової відповіді на це завдання, є чесною грою, але не особливо цікавою.

    Зауважте, що повинен бути перекладач, щоб подати заявку можна перевірити. Дозволяється (і навіть заохочується) писати цього перекладача самостійно для раніше не виконаної мови.

    Також зверніть увагу , що мови дійсно повинні виконувати свої звичайні критерії для мов програмування .

  • Якщо ваша обрана мова є тривіальним варіантом іншої (потенційно більш популярної) мови, на яку вже є відповідь (подумайте, основні або діалекти SQL, оболонки Unix або тривіальні похідні Brainfuck, як Headsecks або Unary), подумайте про додавання примітки до існуючої відповіді, що те саме або дуже схоже рішення є найкоротшим в іншій мові.

  • Якщо вони не були відмінені раніше, застосовуються всі стандартні правила , включаючи http://meta.codegolf.stackexchange.com/q/1061 .

В якості побічної записки, будь ласка, не зволікайте нудних (але дійсних) відповідей мовами, де для гольфу не так багато; вони все ще корисні для цього питання, оскільки він намагається скласти каталог максимально повно. Однак, перш за все, надсилайте відповіді мовами, де автору доводилося докладати зусиль, щоб розібратися в коді.

Каталог

Фрагмент стека внизу цієї публікації генерує каталог з відповідей а) як список найкоротших варіантів для кожної мови та б) як загальний таблиця лідерів.

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

## Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

## Ruby, <s>104</s> <s>101</s> 96 bytes

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

## Perl, 43 + 2 (-p flag) = 45 bytes

Ви також можете зробити ім'я мови посиланням, яке з’явиться у фрагменті:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


52
Bash, 3 байти :cat
TheDoctor

3
@TheDoctor Я думаю, що це потрапить у правило "не використовуйте вбудований, який робить саме те, що потрібно".
Paŭlo Ebermann

5
@ PaŭloEbermann Не існує такого правила, і відповідна стандартна лазівка ​​більше не приймається. (Насправді, вже є shвідповідь, catяка також використовує коротше рішення з використанням dd.)
Мартін Ендер,

1
Якщо тільки він використовував стандартні методи введення та виведення: ///, 0 байт .
Товариш SparklePony

1
@SparklePony За винятком випадків, вам доведеться уникати косої риси та зворотних нахилів.
Мартін Ендер

Відповіді:


73

sed, 0


Порожня sedпрограма робить саме те, що тут потрібно:

$ printf "abc\ndef" | sed ''
abc
def$ 

3
Що станеться, якщо хтось пише yes | tr -d \\n | sed ''?
BenGoldberg

@BenGoldberg За замовчуванням sed працює на рядковій основі, тому в цьому випадку він продовжуватиме розсипання yeses в один буфер візерунка, поки у нього не вичерпається пам'ять. Застереження, напевно, ...
Digital Trauma

POSIX наказує, що простір шаблону повинен мати розмір щонайменше 8192 байт, IIRC. Я знаю, що реалізація GNU має динамічний простір шаблону, обмежений лише наявною пам'яттю, тому ви досить безпечні для цього.
Toby Speight

59

Зіім , 222 201 196 185 182 байт

    ↓ ↓

 ↓ ↓     ↓
 ↗ ↗↙↔↘↖ ↖
 ↓↓⤡⤢  ⤢↙
↘ ↖⤡ ↖
  ↙
  ↕↘ ↑ ↙
→↘↖↑ ↙ ↑
→↖   ↑
→↖↘ ↙
  ↑↓↑

   ⤡

Можливо, це не відображатиметься правильно у вашому браузері, тому ось схема коду:

введіть тут опис зображення

Я не можу придумати простішу структуру, щоб вирішити проблему в Зіімі, але я впевнений, що фактичний код все ще досить зграбний.

Зіім ніяк не може обробляти нескінченні потоки, оскільки надрукувати що-небудь можна лише в кінці програми.

Пояснення

Оскільки у Зііма є досить унікальна модель декларативної схеми управління, імперативний алгоритм псевдокоду тут не виріже. Натомість я поясню основи Зііма та теперішню виправлену структуру вищевказаного коду (аналогічно графічно), як мистецтво ASCII.

Контрольний потік в Ziim відбувається в усьому місці: кожна стрілка, на яку не вказана інша стрілка, ініціалізує "нитку", яка обробляється незалежно від інших (насправді не паралельно, але немає гарантій, в якому порядку вони обробляються , якщо ви не синхронізуєте їх за допомогою конкатенації). Кожна така нитка містить список двійкових цифр, починаючи з {0}. Тепер кожна стрілка в коді - це якась команда, яка має один-два входи та один-два виходи. Точна команда залежить від того, скільки стрілок вказують на неї, з яких орієнтацій.

Ось список команд, де m -> nвказано, що команда приймає mвходи та виробляє nвиходи.

  • 1 -> 1, no-op : просто перенаправляє нитку.
  • 1 -> 1, інвертувати : заперечує кожен біт у потоці (а також переспрямовує його).
  • 1 -> 1, read : замінює значення потоку наступним бітом STDIN або порожнім списком, якщо ми потрапили на EOF.
  • 2 -> 1, з'єднати : це єдиний спосіб синхронізації потоків. Коли нитка потрапить на одну сторону стрілки, вона буде призупинена, поки інша нитка не потрапить на іншу сторону. Після цього вони будуть об'єднані в одну нитку і продовжать виконання.
  • 2 -> 1, label : це єдиний спосіб приєднати різні шляхи виконання. Це просто безвідмовна робота, яка має два можливі входи. Таким чином, нитки, що входять до "мітки" через будь-який маршрут, будуть просто перенаправлені в той же напрямок.
  • 1 -> 2, розділити : бере одну нитку і надсилає дві копії в різних напрямках.
  • 1 -> 1, isZero? : споживає перший біт потоку і надсилає потік в одному з двох напрямків залежно від того, чи був біт 0 або 1.
  • 1 -> 1, isEmpty? : споживає весь список (тобто замінює його порожнім списком) і надсилає потік в одному з двох напрямків залежно від того, чи був список вже порожнім чи ні.

Тож маючи на увазі, ми можемо розробити загальну стратегію. За допомогою конкатенату ми хочемо неодноразово додавати нові біти до рядка, який представляє весь вхід. Ми можемо просто зробити це, перенісши висновок конкатената назад на один із його входів (і ми ініціалізуємо це у порожній список, очистивши a {0}з isEmpty? ). Питання в тому, як ми можемо припинити цей процес.

На додаток до додавання поточного біту ми також додамо 0 або 1, що вказує, чи досягнуто EOF. Якщо ми надішлемо наш рядок через isZero? , він знову позбудеться цього біта, але давайте розрізнемо кінець потоку, і в такому випадку ми просто дозволимо потоку залишити край сітки (через що Ziim надрукує вміст потоку в STDOUT та припинить програму) .

Чи досягнуто ми EOF чи ні, не можна визначити, використовуючи isEmpty? на копії вводу.

Ось діаграма, яку я пообіцяв:

              +----------------------------+   {0} --> isEmpty --> label <--+
              |                            |                    n    |      |
              v                            |                         v      |
    {0} --> label --> read --> split --> split ------------------> concat   |
                                 |                                   |      |
                           n     v     y                             |      |
 inv --> label --> concat <-- isEmpty --> concat <-- label <-- {0}   |      |
  ^        ^          |                     |          ^             |      |
  |        |          v                     v          |             |      |
 {0}       +------- split ---> label <--- split -------+             |      |
                                 |                                   |      |
                                 +-------------> concat <------------+      |
                                                   |                        |
                                              y    v                        |
                         print and terminate <-- isZero --------------------+

Деякі зауваження про те, з чого почати читати:

  • У {0}верхньому лівому куті - початковий тригер, який запускає цикл введення.
  • {0}До верхнього правого кута негайно скидається в порожній список являє собою вихідну рядок , яку ми будемо поступово заповнювати з входом.
  • Інші два {0}s подаються в цикл "виробника" (один перевернутий, один ні), щоб отримати необмежену кількість 0s і 1s, яку нам потрібно додати до рядка.

29
Як ви навіть можете написати таку програму, щоб ваш мозок не вибухнув у мільйон маленьких шматочків тканини.
Ешвін Гупта

40

Шестикутник , 6 байт

Раніше це було 3 байти (див. Нижче), але ця версія не працює довго з останнього оновлення мови. Оскільки я ніколи навмисно не вводив помилку, якою користувалася версія, я вирішив не рахувати її.


Безпроблемне рішення (тобто таке, яке працює з фіксованим перекладачем) виявляється набагато складніше. У мене виникли проблеми із втисненням його в сітку 2x2, але я знайшов одне рішення зараз, хоча мені потрібно цілих 7 байт :

<)@,;.(

Після розгортання отримуємо:

введіть тут опис зображення

Оскільки початковий край пам'яті дорівнює 0, <безумовно відхиляє вказівник інструкції на діагональ Північний Схід, де він переходить на сірий шлях. Це .не-оп. Тепер ,читає байт, )збільшуючи його таким чином, що дійсні байти (включаючи нульові байти) є позитивними, а EOF - 0.

Тож на EOF IP переходить на червоний шлях, де @програма припиняється. Але якщо ми все-таки читаємо байт, то IP переходить на зелений шлях замість того, де (зменшує край до вихідного значення, перш ніж ;надрукувати його на STDOUT. Тепер ІР безумовно повертається назад до сірого шляху, повторюючи процес.


Написавши сценарій грубої сили для моєї відповіді на машині правди, я встановив його, щоб знайти 6-байтове рішення, що не містить помилок, і для програми для котів. Дивно, але він знайшов одне - так, саме одне рішення у всіх можливих шестибайтових програмах шестикутників. Після 50 рішень з машини правди це було досить дивно. Ось код:

~/;,@~

Розгортання:

введіть тут опис зображення

Застосування ~(унарне заперечення) замість того (), що цікаво, адже а) це но-оп на нуль, б) воно поміняє сторони гілки, в) у деяких кодах один ~може бути використаний двічі для скасування операції з собою . Отже ось що відбувається:

Перший раз (фіолетовий шлях) ми проходимо ~це не-оп. /Відображає IP в Північно-Заходу по діагоналі. Тепер сірий шлях читає персонажа і помножує його код символів на -1. Це перетворює коефіцієнт EOF ( -1) у правдиве (позитивне) значення, а всі дійсні символи - хибні (непозитивні) значення. У випадку EOF IP переходить червоний шлях і код припиняється. У випадку дійсного символу IP-адреса бере зелений шлях, де ~скасовується заперечення та ;друкується символ. Повторіть.


Нарешті, ось 3-байтова версія, яка працювала в оригінальній версії інтерпретатора шестикутника.

,;&

Як і у відповіді Лабіринта, і ця завершується помилкою, якщо вхідний потік кінцевий.

Після розгортання коду він відповідає наступній шістнадцятковій сітці:

введіть тут опис зображення

Не .є. Виконання починається на фіолетовому шляху.

,читає байт, ;пише байт. Потім виконання продовжується по лососевому (іш?) Шляху. Нам потрібно &скинути поточний край пам'яті до нуля, таким чином, щоб IP потрапив назад до фіолетового ряду, коли потрапляв у кут в кінці другого ряду. Як тільки ,натисне EOF, він повернеться -1, що спричинить помилку при ;спробі його надрукувати.


Діаграми генеруватися з Timwi дивовижному «s HexagonyColorer .


2
6-байтна версія дуже-дуже розумна. Грубі сили можуть бути неймовірно приголомшливими.
ETHproductions

Чи є у вас посилання на вашого грубого насильника?
MD XF

@MDXF Я не тримаю різних версій навколо, але це завжди якась модифікація цього сценарію Ruby .
Мартін Ендер

36

TeaScript , 0 байт

TeaScript - це лаконічна мова для гольфу, складена на JavaScript


В недавньому оновленні вхід неявно додається як перше властивість.

Спробуйте в Інтернеті


Як варіант, 1 байт

x

xмістить вхід у TeaScript. Вихід неявний


Я збирався опублікувати це :)
Kritixi Lithos

5
Так, я подумав, що "Альтернативно" - це назва мови ...
Quelklef

28

Брайан і Чак , 44 байти

#{<{,+?+}_+{-?>}<?
_}>?>+<<<{>?_}>>.<+<+{<{?

Я спочатку створив цю мову для створення мови програмування, яка видається лише непридатною . Це виявляється дуже приємною вправою для гри в гольф простих проблем.

Основи: Кожен з двох рядків визначає подібну до Brainfuck програму, яка працює на вихідний код іншої програми - перша програма називається Брайан, а друга називається Чак. Читати може лише Брайан, і писати лише Чак. Замість циклів Brainfuck у вас є, ?який передає управління іншій програмі (і ролі вказівника інструкцій та головки стрічки змінюються також). Доповненням до Brainfuck є {і те, }що сканують стрічку для першої ненульової комірки (або лівого кінця). Також _замінюються нульовими байтами.

Хоча я ще не вважаю це оптимальним, я цілком задоволений цим рішенням. Моєю першою спробою було 84 байти, і після кількох сеансів з гольфу зі Sp3000 (і, взявши трохи натхнення від його спроб), мені вдалося повільно знизити його до 44, кілька байт за раз. Особливо блискучим +}+трюком була його ідея (див. Нижче).

Пояснення

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

#Просто заповнювач, оскільки керування перемиканням не виконує осередок ми включили. {<{гарантує, що головка стрічки знаходиться на першій камері Чака. ,читає байт зі STDIN або -1якщо ми потрапляємо на EOF. Таким чином, ми збільшуємо це, +щоб зробити його нульовим для EOF і не-нульовим в іншому випадку.

Припустимо, поки що ми ще не на EOF. Тож комірка позитивна і ?переключить управління на Чак. }>переміщує головку стрічки (на Брайана) до і передає управління назад до Brian.+_?

{-тепер декрементує першу клітинку Чака. Якщо вона ще не дорівнює нулю, ми знову передаємо контроль Чаку ?. Цього разу }>переміщає стрічку на дві клітини Брайана правої останньої ненульової комірки. Спочатку ось що:

#{<{,+?+}_+{-?>}<?__
                   ^

Але згодом ми вже будемо мати деяких персонажів. Наприклад, якщо ми вже читали та друкували abc, то це виглядатиме так:

#{<{,+?+}_+{-?>}<?11a11b11c__
                            ^

Де 1s - насправді 1-байт (ми побачимо, про що пізніше).

Ця комірка завжди буде нульовою, тому цього разу контроль ? не зміниться. >переміщує ще одну клітинку праворуч і +збільшує цю клітинку. Ось чому перший символ у вводі закінчується трьома клітинками праворуч від ?(і кожна наступна одна три комірки далі праворуч).

<<<повертається до останнього символу у цьому списку (або, ?якщо це перший символ), і {>повертається до +стрічки Брайана, щоб повторити цикл, який повільно переносить вхідну комірку на кінець стрічки Брайана.

Після того, як ця вхідна комірка порожня, ?після цього {-більше не буде перемикати управління. Потім >}<переміщує головку стрічки на Чак до _та перемикає керування таким чином, щоб замість нього виконувалася друга половина Чак.

}>>переміщується до клітинки, про яку ми писали зараз, наприкінці стрічки Брайана, що є байтом, який ми прочитали зі STDIN, тому ми друкуємо його назад .. Для того , щоб }пробігти повз цього нового символу на стрічці , ми повинні ліквідувати розрив двох нульових байтів, тому ми збільшуємо їх 1з <+<+(так ось чому є 1-байт між фактичними символами на фінальній стрічці). Нарешті {<{повертається назад до початку стрічки Брайана і ?починає все з початку.

Вам може бути цікаво, що станеться, якщо символ, який ми читали, був нульовим байтом. У такому випадку щойно написана клітинка сама по собі буде нульовою, але оскільки вона знаходиться в кінці стрічки Брайана і нам не байдуже, де цей кінець, ми можемо просто проігнорувати це. Це означає, що якби введення було ab\0de, то стрічка Брайана насправді виглядала б так:

#{<{,+?+}_+{-?>}<?11a11b1111d11e

Нарешті, щойно ми потрапимо на EOF, що першим ?на стрічці Брайана стане безвідмовно. У цей момент ми припиняємо програму. Наївне рішення було б перейти до кінця стрічки і перемикача управління Чаком, таким чином, що програми termiantes: >}>}<?. Тут дійсно розумна ідея Sp3000 економить три байти:

+перетворює першу клітину Чака в 1. Це означає, }що є відправною точкою і знаходиться _в середині стрічки Чака. Замість того, щоб пропускати повз нього, ми просто закриваємо прогалину, перетворюючи її також на 1с +. Тепер давайте подивимося, що решта коду Брайана відбувається з цим модифікованим Чак ...

{повертається до першої комірки Чака, як завжди, і -перетворює її назад в нульовий байт. Це означає, що ?це не-оп. Але тепер >}<, який, як правило, переміщав стрічку на середину стрічки Чака, рухається прямо повз неї до кінця стрічки Чака, а ?потім передає керування Чаку, припиняючи код. Приємно, коли все просто виходить ... :)


25

Хаскелл, 16 байт

main=interact id

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


23

sh + binutils, 3 2 байти

dd

Ну, не зовсім очевидно. Від @ Random832

Оригінал:

cat

Болісно очевидний ...: D


12
Я зроблю один краще: dd.
Випадково832

Я збирався зайнятися котом ... D:
ev3commander

1
Так, це чудово і все ... але 170 повторень для набору тексту cat???
MD XF

1
@MDXF а як же хто знає, скільки реп із segfault? ;)
caird coinheringaahing

23

Funciton , 16 байт

╔═╗
╚╤╝

(Зашифровано як UTF-16 з BOM)

Пояснення

Поле повертає вміст STDIN. Вільний кінець виводить його.


19

Код машини Motorola MC14500B , 1,5 байти

Написано шістнадцятковим:

18F

Написано двійковою мовою:

0001 1000 1111

Пояснення

1   Read from I/O pin
8   Output to I/O pin
F   Loop back to start

Опкоди - 4 біти кожен.


1
-1 немає скріншота, приклад або Спробуйте посилання в Інтернеті: P (jk)
MD XF

2
+1. Єдиний спосіб, з яким я можу придумати оптимізацію цього, - це просто припаяти вхідний штифт до вихідного штифта і вийняти мікросхему з розетки: P
Wossname


15

Brainfuck, 5 байт

,[.,]

Еквівалентний псевдокоду:

x = getchar()
while x != EOF:
    putchar(x)
    x = getchar()

Це обробляє нескінченні потоки, але розглядає нульові байти як EOF. Те, чи BF може правильно обробити нульові байти, залежить від реалізації до реалізації, але це передбачає найпоширеніший підхід.


1
ДАРИТИ! Ти побив мене до цього 5 хвилин!
kirbyfan64sos

Якщо першим символом є NULL, він не запуститься правильно. Так має бути +[,.]правильно?
Шельваку

6
@Shel Для використання 0x00 як байт EOF. Якщо перший символ - EOF, він нічого не друкує, працюючи так, як очікувалося.
Mego

2
"псевдокод", давай, це явно просто невкручений, не крапкою з комою C: P
MD XF

14

Лабіринт , 2 байти

,.

Якщо потік є кінцевим, це закінчується помилкою, але весь вихід, отриманий помилкою, переходить до STDERR, тому стандартний вихідний потік правильний.

Як і в Brainfuck, він ,читає байт (натискаючи його на основний стек Лабіринту) і .пише байт (вискакуючи з основного стека Лабіринту).

Причина цього циклу полягає в тому, що обидва ,і .є "тупиками" у (дуже тривіальному) лабіринті, представленому вихідним кодом, таким чином, що вказівник інструкції просто обертається на місці і повертається назад до іншої команди.

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


Для довідки, ми можемо вирішити це без помилки в 6 байт наступним чином

,)@
.(

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


13

C, 40 байт

main(i){while(i=~getchar())putchar(~i);}

main () {while (255-putchar (getchar ()));}} на пару байтів коротший.
Алхімік

1
На жаль, він передчасно виходить з байтів 0xFF і додає до входу 0xFF байт, якщо він не містить його.
Денніс

Що з наступного, 36 байт: main () {for (;; putchar (getchar ()));};
Йохан дю Тойт

@ user2943932 Коли він потрапляє на EOF, getcharповертається -1 , тож ваш код надрукує нескінченний потік 0xFF байт після (кінцевого) вводу.
Денніс

12

> <> , 7 байт

i:0(?;o

Спробуйте тут . Пояснення:

i:0(?;o
i        Take a character from input, pushing -1 if the input is empty
 :0(     Check if the input is less than 0, pushing 1 if true, 0 if false
    ?;   Pop a value of the top of the stack, ending the program if the value is non-zero
      o  Otherwise, output then loop around to the left and repeat

Якщо ви хочете, щоб продовжувати йти , поки ви не дасте йому більше вхідного сигналу, замініть ;з !.


Aww man, я сподівався опублікувати> <> відповідь ...: P (+1!)
El'endia Starman

1
io(2 байти) робить те саме, але виходить з ладу і записує something smells fishy...в STDERR в кінці виконання, що дозволено.
Лінн

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

11

X86 збірка, 70 байт

Розбирання за допомогою objdump:

00000000 <.data>:
   0:   66 83 ec 01             sub    sp,0x1
   4:   66 b8 03 00             mov    ax,0x3
   8:   00 00                   add    BYTE PTR [eax],al
   a:   66 31 db                xor    bx,bx
   d:   66 67 8d 4c 24          lea    cx,[si+0x24]
  12:   ff 66 ba                jmp    DWORD PTR [esi-0x46]
  15:   01 00                   add    DWORD PTR [eax],eax
  17:   00 00                   add    BYTE PTR [eax],al
  19:   cd 80                   int    0x80
  1b:   66 48                   dec    ax
  1d:   78 1c                   js     0x3b
  1f:   66 b8 04 00             mov    ax,0x4
  23:   00 00                   add    BYTE PTR [eax],al
  25:   66 bb 01 00             mov    bx,0x1
  29:   00 00                   add    BYTE PTR [eax],al
  2b:   66 67 8d 4c 24          lea    cx,[si+0x24]
  30:   ff 66 ba                jmp    DWORD PTR [esi-0x46]
  33:   01 00                   add    DWORD PTR [eax],eax
  35:   00 00                   add    BYTE PTR [eax],al
  37:   cd 80                   int    0x80
  39:   eb c9                   jmp    0x4
  3b:   66 b8 01 00             mov    ax,0x1
  3f:   00 00                   add    BYTE PTR [eax],al
  41:   66 31 db                xor    bx,bx
  44:   cd 80                   int    0x80

Джерело:

sub esp, 1
t:
mov eax,3
xor ebx,ebx
lea ecx,[esp-1]
mov edx,1
int 0x80
dec eax
js e
mov eax,4
mov ebx,1
lea ecx,[esp-1]
mov edx,1
int 0x80
jmp t
e:
mov eax,1
xor ebx,ebx
int 0x80

1
Отже, objdumpрозібрали його як 32-бітний код, тоді як, здається, ви склали як 16-бітний. У що вірити? Оскільки ви використовуєте int 0x80, я думаю, це призначено для Linux, але навіщо тоді компілювати як 16-розрядний?
Руслан

@Ruslan Я навіть не усвідомлював, що він був складений у 16-бітовій ...
kirbyfan64sos

11

Універсальна лямбда , 1 байт

!

Універсальна програма лямбда - це кодування ламбда-терміна у двійковій формі, нарізаній шматками по 8 біт, заповнення неповних фрагментів будь-якими бітами, перетвореними в потік байтів.

Біти перекладаються на лямбда-термін наступним чином:

  • 00 вводить лямбда-абстракцію.
  • 01 являє собою застосування двох наступних термінів.
  • 111..10, з n повторень біта 1, відноситься до змінної n- ї батьківської лямбда; тобто це індекс De Bruijn в одинаковому.

Таким перетворенням 0010є функція ідентичності λa.a, що означає, що будь-яка однобайтова програма форми 0010xxxxє catпрограмою.


1
Але !хіба 0x21ні 0x4_?
wchargin

Виправлено. --------
Лінн

10

PowerShell, 88 41 30 байт

$input;write-host(read-host)-n

EDIT - забув, що я можу використовувати $inputавтоматичну змінну для вводу в трубопровід ... EDIT2 - не потрібно перевіряти наявність$input

Так, так ... STDIN в PowerShell ... дивно, чи будемо ми говорити. З припущенням, що нам потрібно прийняти дані від усіх типів STDIN, це одна з можливих відповідей у ​​цьому каталозі, і я впевнений, що є й інші. 1

Хоча введення трубопроводу в PowerShell не працює, як ви думали. Оскільки трубопроводи в PowerShell є функцією мови, а не функцією середовища / оболонки (а PowerShell так чи інакше не є виключно мовою), є деякі химерності до поведінки.

Для початківців і найбільш важливих для цього запису труба не оцінюється миттєво (більшу частину часу). Значення, якщо ми маємо command1 | command2 | command3в нашій оболонці, command2не братиме введення або почати обробку , поки command1НЕ буде завершено ... якщо ви не инкапсулировать command1з ForEach-Object... який відрізняється ніж ForEach. (хоча ForEachце псевдонім для ForEach-Object, але це окреме питання, оскільки я говорю ForEachяк твердження, а не псевдонім)

Це означає, що щось на кшталт yes | .\simple-cat-program.ps1(хоча yesнасправді не існує, але все-таки) не буде працювати, тому yesщо ніколи не закінчиться. Якби ми могли це зробити ForEach-Object -InputObject(yes) | .\simple-cat-program.ps1, треба (теоретично) працювати.

Знайомство з ForEach та ForEach-Object на Microsoft "Ей, сценарій хлопець!" блог.

Отже, всі ці пункти пояснюють, чому if($input){$input}існує. Ми беремо параметр введення, який спеціально створюється автоматично, якщо вхід трубопроводу присутній, перевіряємо, чи він існує, і якщо так, виводимо його.

Потім ми беремо дані від користувача (read-host)за тим, що по суті є окремим потоком STDIN, і write-hostповертаємо його назад із -nпрапором (скорочено для -NoNewLine). Зауважте, що це не підтримує введення довільної довжини, оскільки воно read-hostзавершиться лише тоді, коли буде введено стрічковий канал (технічно, коли користувач натисне "Enter", але функціонально еквівалентний).

Phew.

1 Але є й інші варіанти:

Наприклад, якщо нас цікавило лише введення трубопроводу, і нам не потрібна повна програма, ви можете зробити щось на кшталт, | $_яке б просто виводило будь-який вхід. (Взагалі, це дещо зайве, оскільки PowerShell має неявний вихід із речей, «залишених» після розрахунків, але це вбік.)

Якщо нас цікавить лише інтерактивний ввід користувача, ми можемо використовувати просто write-host(read-host)-n.

Крім того, ця функція має особливість химерності прийому введення командного рядка, наприклад .\simple-cat-program.ps1 "test", заповнить (а потім виведе) $aзмінну.


не забувайте побудований у псевдонімах!
Чад Бакстер

10

Cubix , 6 5 байт

Тепер обробляє нульові байти!

@_i?o

Cubix - це двовимірний езоланг на основі стека. Cubix відрізняється від інших 2D язиків тим, що вихідний код обмотаний навколо куба.

Перевірте це в Інтернеті! Примітка: між ітераціями затримка 50 мс.

Пояснення

Перше, що робить перекладач - це розібрати найменший кубик, на який впишеться код. У цьому випадку довжина ребра дорівнює 1. Потім код прокладений без опу, .поки всі шість сторін не заповнені. Білий простір видаляється перед обробкою, тому цей код ідентичний наведеному:

  @
_ i ? o
  .

Тепер код запускається. IP (покажчик інструкції) починається на лівій крайній стороні, вказуючи на схід.

Перший символ IP - зближень _, який є дзеркалом , яке перетворює IP навколо , якщо він стикається на північ або на південь; в даний час вона стоїть на сході, тому це нічого не робить. Далі i, який вводить байт зі STDIN. ?повертає IP вліво, якщо верхній елемент негативний, або праворуч, якщо він є позитивним. Тут є три можливі шляхи:

  • Якщо введений байт дорівнює -1 (EOF), IP повертає ліворуч і натискає @, що завершує програму.
  • Якщо введений байт дорівнює 0 (нульовий байт), IP просто продовжується прямо, виводячи байт з o.
  • В іншому випадку IP повертає праворуч, пересувається по нижній частині обличчя і потрапляє в дзеркало _. Це обертає його, відсилає його назад до ?, що знову повертає його праворуч і видає байт.

Я думаю, що ця програма є оптимальною. Перш ніж Cubix міг обробляти нульові байти (EOF був 0, а не -1), ця програма працювала для всього, крім нульових байтів:

.i!@o

Я написав грубий форсер, щоб знайти всі 5-байтні програми для котів. Незважаючи на те, що до кінця потрібно ~ 5 хвилин, остання версія знайшла 5 програм:

@_i?o   (works as expected)
@i?o_   (works in exactly the same way as the above)
iW?@o   (works as expected)
?i^o@   (false positive; prints U+FFFF forever on empty input)
?iWo@   (works as expected)

Будь ласка, не редагуйте відразу десяток публікацій. Ти заливаєш титульну сторінку. 3 за часом не є проблемою, але якщо вам доведеться зробити більше, то, будь ласка, робіть свої зміни невеликими партіями кожні 12 годин.
Мартін Ендер

@MartinEnder Вибачте, я щойно це помітив. Я буду надавати їх у майбутньому.
ETHproductions

9

Віци, 2 байти

zZ

zотримує весь вхідний стек і підштовхує його до активного стеку програми. Zвиводить усі активні стеки в STDOUT.

Альтернативний метод:

I \ il \ O
I \ Повторюйте наступний символ для введення довжини стека.
  i Візьміть предмет із входу.
   l \ Повторіть наступний символ для довжини поточного стеку програми.
     O Виведіть верхній елемент стека як символ.

2
^ _ ^ Майте +1 у будь-якому випадку! :)
El'endia Starman

Шкода голосів, мій улюблений!
Аддісон Кримп

Чому голоси? Здається, це ідеально правильний запис
Conor O'Brien

1
Він є дійсним усіма специфікаціями.
Аддісон Кримп

9

MarioLANG , 11 байт

,<
."
>!
=#

Я не зовсім впевнений, що це оптимально, але це найкоротше, що я знайшов.

Це підтримує нескінченні потоки і закінчуватиметься помилкою при досягненні EOF (як мінімум, реалізація посилання Ruby).

Є ще одна версія цієї версії, яка перетворює Маріо в ніндзя, який може подвійно стрибати:

,<
.^
>^
==

У будь-якому випадку Маріо починає падати вниз по лівій колонці, де ,читає байт і .записує байт (який видає помилку в EOF, оскільки ,не повертає дійсного символу). >гарантує, що Маріо прямує праворуч ( =це лише грунт для нього ходити далі). Потім він рухається вгору, або через подвійний стрибок з ^або через ліфт (той "і #пара) перед тим, як <сказати йому перейти назад до лівої колони.


8

rs , 0 байт


Серйозно. rs просто друкує все, що отримується, якщо даний сценарій повністю порожній.


7

GolfScript, 3 байти

:n;

Порожня програма перегукується зі стандартним входом. Мова не може обробити нескінченні потоки. Однак він додає новий рядок, як згадував @Dennis. Це робиться шляхом загортання всього стека в масив і виклику puts, який визначається як print n print, де nє новий рядок. Однак ми можемо переосмислити nSTDIN, а потім виповнити стек, саме це і :n;робиться.


7

Напіврозбита машина в інтенсивному русі , 9 + 3 = 12 байт

#<
o^<
 v

Напіврозбитий автомобіль у великому трафіку (HBCHT) приймає введення як аргументи командного рядка, тому біжіть як

py -3 hbcht cat.hbc -s "candy corn"

Зверніть увагу, що +3 призначений для -sпрапора, який видається як символи. Крім того, HBCHT не здається обробляти NUL, оскільки всі нулі випадають з виводу (наприклад 97 0 98, виводиться у вигляді двох знаків ab).

Пояснення

У HBCHT ваш автомобіль стартує на виїзді, oа ваша мета - вихід #. ^>v<спрямовуйте рух автомобіля, одночасно змінюючи стрічку, схожу на BF ( ^>v<перекладіть на +>-<). Однак, як свідчить назва мови, ваш автомобіль може повернути лише направо - будь-які спроби повернути ліворуч повністю ігноруються (включаючи їх ефекти на пам'ять). Зауважте, що це лише для повороту - ваш автомобіль цілком здатний рухатись вперед / назад.

Інші цікаві частини щодо HBCHT - це те, що початковий напрямок вашого автомобіля є рандомізованим, а сітка - тороїдальною. Таким чином, нам просто потрібна машина, щоб доїхати до виходу, не змінюючи стрічки для всіх чотирьох початкових напрямків:

  • Вгору та вниз прямо, спрямовуючись безпосередньо до виходу.

  • Зліва ми обертаємо, виконуємо <та збільшуємо ^. Ми не можемо повернути ліворуч на наступному, <тому обертаємо і зменшуємо v, відкидаючи попередній приріст. Оскільки ми прямуємо вниз зараз, ми можемо повернути праворуч на <виїзд та виїхати, перемістивши вказівник двічі та змінивши відсутність значень комірок.

  • Праворуч робимо те саме, що і ліворуч, але пропускаємо перше, ^оскільки не можемо повернути ліворуч.


Редагувати : Виявляється, що інтерпретатор HBCHT дозволяє вам виконати лише один шлях через прапор командного рядка, наприклад

py -3 hbcht -d left cat.hbc

Однак, не тільки прапор занадто дорогий для цього конкретного питання (принаймні, 5 байт для " -d u"), здається, що всі шляхи все ще повинні мати можливість зробити його до виходу для виконання коду.


7

Міколанг , 5 байт

od?.O

Спробуйте тут.

Пояснення

oзчитує символ із введення та висуває його ASCII-код на стек ( 0якщо вхід порожній). dпотім дублює верхню частину стека (символ, який щойно прочитали). ?- це умовний батут, який перестрибує наступну інструкцію верхньої частини стека 0. Якщо вхід був порожнім, значення " .не" стрибнуло і програма зупиняється. В іншому випадку Oвиводиться вершина стека як символ. Тороїдальна природа Мінколанга означає, що це петлі навколо до початку.


2
Грар! Ти побив мою мову! Неприйнятний! +1
Addison Crump

7

INTERCALL , 133 байт

ват

INTERCALL IS A ANTIGOLFING LANGUAGE
SO THIS HEADER IS HERE TO PREVENT GOLFING IN INTERCALL
THE PROGRAM STARTS HERE:
READ
PRINT
GOTO I

Схоже, хтось справді грав у гольф суто проти гольфної мови ... 133-116 = 17
Ерік Атгольфер

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Оскільки програма з кішками досить проста, це стосується не всіх програм ... codegolf.stackexchange.com/a/82748/53745
TuxCrafting

Людина, яка склала мову, мала намір використовувати римські цифри, але якби це було надрукувати 500(не впевнений), було б PRINT D, правда? (без урахування заголовка)
Ерік Аутгольфер

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Ні, INTERCALL може друкувати лише символи ASCII та використовувати стек, так, наприклад, для друку caracter зі значенням ascii 20 код є PUSH XX<newline>PRINTабо PUSH XX AND PRINT. О, і я творець INTERCALL
TuxCrafting

7

V , 0 байт

Спробуйте в Інтернеті!

Ідея V про «пам’ять» - це просто гігантський 2D масив символів. Перед запуском будь-якої програми весь вхід завантажується в цей масив (відомий як "Буфер"). Потім в кінці будь-якої програми друкується весь текст у буфері.

Іншими словами, порожня програма - це програма для котів.


6

Сніговик 1.0.2 , 15 символів

(:vGsP10wRsp;bD

Взято безпосередньо з examplesкаталогу Сніговика . Читає рядок, друкує рядок, читає рядок, друкує рядок ...

Зауважте, що через деталі реалізації, коли STDIN буде порожнім, vgповернеться те саме, що і для порожнього рядка. Тому це буде неодноразово друкувати нові рядки у нескінченному циклі, коли STDIN буде закритий. Це може бути виправлено у майбутній версії.

Пояснення коду:

(        // set two variables (a and f) to active—this is all we need
:...;bD  // a "do-loop" which continues looping as long as its "return value"
         // is truthy
  vGsP   // read a line, print the line
  10wRsp // print a newline—"print" is called in nonconsuming mode; therefore,
         // that same newline will actually end up being the "return value" from
         // the do-loop, causing it to loop infinitely

5

FireType , 7 байт

,
&
_
=

Вимагає деяких змін, які я щойно натиснув . Правила кажуть:

На відміну від наших звичних правил, сміливо користуйтесь мовою (або мовною версією), навіть якщо вона є новішою, ніж ця проблема.

значить, я в чистоті!


5

Ділення , 4 байти

R?J!

Хіба не приємно, коли ви перемагаєте зразкові програми у власному сховищі мови? :) Для довідки, він має 7-байтне рішення

R?J0;0!

Пояснення

Отже, Rпочинається керуючий потік з правого атома. ?зчитує символ з STDIN в масу атома. Поки ми читаємо символи, енергія залишається нульовою, тому Jump не працює і !друкує персонажа. Атом циклічно повертається до початку ( Rтепер не працює) і повторює весь процес.

Коли ми натиснемо EOF, ?встановимо енергію атома 1, тому Jump тепер пропустить команду print. Але коли атом потрапляє ? після повернення EOF, він замість цього знищить атом, що припиняє програму.

(Рішення від автора мови використовує явне ;для завершення програми, яке пропускається двома 0частками в іншому випадку.)


5

Штрипед , 20 байт

e )
"
 r )
 s )
 "
"

Це примхливо демонструє, що майже будь-який рядок ASCII для друку є дійсним ідентифікатором у Shtriped.

Як це працює:

e )   \ declares a variable named )
"     \ defines a function with 0 arguments named "
 r )  \ gets a line of string input, saving it to )
 s )  \ prints ) as a string
 "    \ recursively calls ", effectively looping forever
"     \ calls " from the main scope to get things started

Немає реального способу виявити EOF, тому ця петля назавжди подобається відповіді Python .

Ви можете легко зупинити його, якщо введено порожній рядок (30 байт):

e )
"
 r )
 d ) \ tries to decrement ), if it was the empty string, aka 0, it can't, so 0 is returned all the way up
 i ) \ increment ) to put it back to normal after possibly decrementing
 s )
 "
"

Зауважте, що Shtriped I / O підтримує лише друковані ASCII , вкладки, канали ліній, повернення каретки, вертикальні вкладки та канали форм (загалом 100 символів). Це тому, що всередині рядки представляються як негативні цілі довільної точності, і для кодування всіх рядків повинен бути кінцевий алфавіт символів.

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