Привіт Світ привіт


66

Наприкінці вашого інтерв'ю Злий інтерв'юер каже вам: "Ми змушуємо всіх наших претендентів пройти короткий тест кодування, щоб побачити, чи дійсно вони знають, про що говорять. Не хвилюйтесь; це легко. І якщо ви створите робочу програму, я запропоную вам роботу негайно ". Він жестикулює вам сісти за сусідній комп’ютер. "Все, що вам потрібно зробити, - це створити робочу програму Hello World. Але" - і він широко посміхається - "є улов. На жаль, єдиний у нас компілятор на цій машині має невелику помилку. Він випадковим чином видаляє одного символу з файл вихідного коду перед компілюванням. Добре, побачимось через п’ять хвилин! " І він виходить із кімнати, радісно свистячи.

Чи можете ви гарантувати, що ви отримаєте роботу?

Задача

Напишіть програму, яка надрукує Hello, world!стандартний вихід навіть після того, як один символ буде видалений з будь-якого місця у файлі. Або підійти якомога ближче до цього.

Правила

Ніякого стороннього виходу - Hello, world!повинна бути єдиною істотною справою, надрукованою на стандартному виході. Добре включати інших символів, якщо вони природним чином створені вашою обраною мовою - наприклад, зворотний новий рядок або навіть щось на зразок [1] "Hello, world!"(наприклад, якщо ви використовували R), але він повинен друкувати абсолютно те саме, щоразу. Наприклад, він не може друкувати Hello, world!Hello, world!або Hello world!" && x==1якийсь час. Однак попередження дозволені.

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

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

Тривіальні рішення, такі як "Hello, world!"декілька мов (оцінка 15), є прийнятними, але перемогти не збираються. Я принаймні знайшов рішення Perl з оцінкою 4, яке я опублікую в підсумку.

Оновлення: Офіційний переможець використовуватиме мову програмування, заповнену Тьюрінгом, і не буде використовувати жодного заздалегідь визначеного механізму, який друкує Hello, world!. Будь-який зовнішній ресурс (крім стандартних бібліотек для вашої мови), який використовується, вважається частиною вашої програми та підлягає тому самому видаленню з 1 символу. Ці вимоги були прикріплені до письмового письма. Вибачте, якщо ви спочатку їх не бачили.

Оновлення 2: Так, ваша програма повинна реально виконати описане вище завдання, щоб отримати бал! Це означає, що вона повинна бути успішно надрукована Hello, world!хоча б раз Це мало бути очевидним. Перемикачі командного рядка та інші налаштування, що додають функціональність, також вважаються частиною вашої програми і підлягають видаленню одного символу. Програма повинна виконати своє завдання без будь-якого введення користувачем. Неможливість складання рахунків у вашому рахунку відмов.

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

Сценарій тесту Perl:

use warnings;
use strict;

my $program   = 'test.pl';
my $temp_file = 'corrupt.pl';
my $command = "perl -X $temp_file"; #Disabled warnings for cleaner output.
my $expected_result = "Hello, world!";

open my $in,'<',$program or die $!;
local $/;           #Undef the line separator   
my $code = <$in>;   #Read the entire file in.

my $fails = 0;
for my $omit_pos (0..length($code)-1)
{
    my $corrupt = $code;
    $corrupt =~ s/^.{$omit_pos}\K.//s;  #Delete a single character

    open my $out,'>',$temp_file or die $!;
    print {$out} $corrupt;  #Write the corrupt program to a file
    close $out;

    my $result = `$command`;    #Execute system command.
    if ($result ne $expected_result)
    { 
        $fails++;
        print "Failure $fails:\nResult: ($result)\n$corrupt";
    }
}

print "\n$fails failed out of " . length $code;

1
Чи може вилучений символ призвести до того, що програма не збирається? Це все ще вважається непрацюючим?
lochok

@lochok, так, це вважатиметься невдачею. Будь-який видалений символ, який призводить до Hello, World!недруку, є помилкою.

2
Подібне запитання: codegolf.stackexchange.com/questions/4486/…
mowwwalker

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

Чи можете ви навести приклад "комутаторів командного рядка та інших налаштувань, що додають функціональність"? Ви маєте на увазі перемикачі та налаштування, задані самою програмою, або використовуючи перемикачі та налаштування в середовищі збирання?
CasaDeRobison

Відповіді:


129

Befunge, оцінка 0

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

EDIT : багато спростили.

                              vv
@,,,,,,,,,,,,,"Hello, world!"<<
@,,,,,,,,,,,,,"Hello, world!"<<

Коротке пояснення потоку:

  1. Befunge починає виконувати зліва вліво, рухаючись праворуч. Простори нічого не роблять.
  2. v повертає потік виконання вниз, так що воно йде вниз на одну лінію.
  3. < повертає потік виконання ліворуч, тому він читає рядок 2 у зворотному порядку.
  4. "Hello, world!"просуває рядок до стека. Він висувається в зворотному порядку, тому що ми виконуємо право наліво.
  5. ,вискакує персонаж і друкує його. Останній натиснутий символ надрукується спочатку, який ще раз повертає рядок.
  6. @ припиняє програму.

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

4
Настільки просто перевірити та не брати участь у обговоренні. Геніальний!
Karma Fusebox

Вітаємо з відмінним рішенням.

2
Я знаю, що це не код-гольф , але ось версія в 66 байт .
MD XF

42

Perl, оцінка 0

(147 символів)

Ось моє рішення, яке мені вдалося досягти від 4 до 0:

eval +qq(;\$_="Hello, world!";;*a=print()if length==13or!m/./#)||
+eval +qq(;\$_="Hello, world!";;print()if*a!~/1/||!m/./#)##)||
print"Hello, world!"

Це повинно з’явитися всі в одному рядку для роботи; перерви у рядках призначені лише для "читабельності".

Це виграє від патологічно вседозволеного синтаксису Перла. Деякі основні моменти:

  • Бареври, які не розпізнаються, трактуються як рядки. Тож, коли evalстає evl, це не помилка, якщо рядок допустимий у цій точці.
  • Унарний +оператор, який не робить нічого, крім розрізнення синтаксису в певних ситуаціях. Це корисно для вищезазначеного, тому що function +argument(де + є нерівномірним) стає string + argument(додаванням), коли ім'я функції змінено і стає рядком.
  • Багато способів оголошення рядків: рядок з подвійним цитуванням qq( )може стати рядком з одним котируванням q(); рядок, обмежений дужками, qq(; ... )може стати рядком, розділеним крапкою з комою qq; ... ;. #всередині рядків можна усунути проблеми з балансуванням шляхом перетворення речей у коментарі.

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


13
+1 для розривів рядків призначені лише для читання ...
Бакуріу,

40

HQ9 +

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

HH

Коли я починаю?


1
Це виробляє "привіт, світ", хоча, а не "Привіт, світ!" як зазначено.
Пол Р

16
Дурниця, мова була просто неправильно вказана у вікі esolang;)
skeevey

11
Добре для вас, якщо у них на комп’ютері для інтерв'ю є компілятор HQ9 + ... :)

Ви можете написати власний компілятор помилок.
PyRulez

2
@ mbomb007 Цей інтерпретатор друкує Hello, world!для Hкоманди.
Денніс

12

Befunge-98 , оцінка 0, 45 байт

20020xx""!!ddllrrooww  ,,oolllleeHH""cckk,,@@

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

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

Пояснення

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

"!dlrow ,olleH"ck,@

Спочатку натискаємо всі відповідні коди символів на стек за допомогою "!dlrow ,olleH". Тоді ck,означає надрукувати верхню частину стека ( ,), 13 ( cплюс 1) рази ( k). @припиняє програму.


11

J, 7 балів

Вибір кожної літери з непарною позицією:

   _2{.\'HHeellllo,,  wwoorrlldd!!'
Hello, world!

5
Те ж саме в golfscript б 4 бали:'HHeelllloo,, wwoorrlldd!!'2%
cardboard_box

@cardboard_box Не соромтеся надіслати його. :)
randomra

Оновлення, тому що я розумію це, і це не відчуває себе як обман.
Майкл Стерн

3

Befunge-93, оцінка 0 (63 байти)

Я знаю, що це не проблема кодового гольфу, але я подумав, що буде цікаво дізнатися, чи можна було б покращити існуюче рішення Befunge-93 з точки зору розміру. Я спочатку розробив цю методику для використання в подібній помилці Error 404 , але потреба в обгортанні корисного навантаження в цьому випадку зробила рішення 3 рядків більш оптимальним.

Це не так добре, як відповідь Мартіна Befunge-98, але це все ще досить суттєве зменшення виграшного рішення Befunge-93.

<>>  "!dlrow ,olleH">:#,_@  vv
  ^^@_,#!>#:<"Hello, world!"<<>#

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

Пояснення

Існує дві версії корисного навантаження. Для незмінної програми перша <спричиняє виконання програми праворуч ліворуч, загортаючись до кінця рядка, поки вона не досягне її vспрямування вниз до другого рядка і не <направить її ліворуч у версію зліва направо корисного навантаження.

Помилка другого рядка призводить до того, що фінал <зміщується вліво і замість нього >направляє потоку направо. Команда #(bridge) не має нічого перестрибувати, тому код просто продовжується, поки він не завернеться і не досягне a ^на початку рядка, направляючи його до першого рядка, а потім >направляючи його праворуч праворуч- ліва корисна навантаження.

Більшість помилок у першому рядку просто призводять до того, що остаточні vкоманди зміщуються на одну, але це не змінює основний потік коду. Видалення першого <дещо інше - в цьому випадку шлях виконання просто перетікає прямо в поле зліва направо навантаження в першому рядку.

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

Якщо є сумніви, я також перевірив сценарій perl, і він підтвердив, що "0 не вдалося з 63".


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