Создание интерпретатора HQ9 +

31

Цель этого кода golf - создать интерпретатор для языка программирования HQ9 +.
В этом языке программирования есть 4 команды:

  • H - печатает "Привет, мир!"
  • Q - печатает исходный код программы
  • 9 - печатает текст песни "99 бутылок пива"
  • + - увеличивает аккумулятор

Правила:

  1. Поскольку аккумулятор не определен, вы можете игнорировать команду +
  2. Ваша программа должна запросить ввод (этот ввод будет исходным кодом) или исходный код читается из файла
  3. Вы не можете помещать текст «99 бутылок пива» в файл и читать текст из файла.
  4. Вам не разрешается использовать алгоритм сжатия, такой как GZip или BZip, для сжатия текста песни: вы должны создать свой собственный алгоритм сжатия. Это не должен быть сложный алгоритм, но постарайтесь максимально сжать текст (помните: это код-гольф, код с наименьшим количеством байтов выигрывает)
  5. Если исходный код содержит символ, который не является H , Q , 9 или + , выведите «Исходный код содержит недопустимые символы» перед выполнением любых команд! Это означает, что, если исходный код, H1например, не выводится Hello, world!до вывода Source code contains invalid characters. Нет, сразу выводSource code contains invalid characters
  6. Если ваш переводчик принимает символы как в верхнем, так и в нижнем регистре, то вы получите -8 к вашему количеству символов

Удачи!

ProgramFOX
источник
3
Правило 4 не имеет смысла в «почему он запрещает это ?!» уровень; Правило 5 не имеет смысла в «что он имеет в виду ?!» уровень.
Питер Тейлор
4
Как правило 5 не имеет смысла?
Майк C
Я думаю, что было бы лучше просто потребовать, чтобы он использовал только верхний регистр, а не произвольно утверждать, что вы получаете бесплатные 8 символов, если он принимает либо. 8 может или не может покрыть это в зависимости от языка.
Майк C
10
Правило 5 не имеет смысла, потому что оно нарушает спецификации HQ9 +.
Boothby
2
Переводчик в HQ9 + должен автоматически победить.
TheNumberOne

Ответы:

16

APL (Dyalog) (326 - 8 = 318)

Вставьте его в окно редактора и позвоните H. Ввод взят с клавиатуры.

H
⎕←'Source code contains invalid characters'/⍨~∧/'HhQq9+'∊⍨V←⍞
B←' of beer'
W←' on the wall'
L←⎕TC[2]
Z←{k←' bottle','s'/⍨⍵≠1⋄⍵<0:'99',k⋄⍵=0:'No',k⋄k,⍨⍕⍵}
{⍵∊'Hh':⎕←'Hello, world!'
⍵∊'Qq':⎕←V
⍵∊'9':{⎕←G,K,(G←Z⍵),B,L,(⊃'Go to the store and buy some more' 'Take one down and pass it around'[1+×⍵]),L,(Z⍵-1),K←B,W,L}¨1-⍨⌽⍳100}¨V
Мэринус
источник
6

Mathematica, 349 346 341 символ

h = If[StringMatchQ[#, ("H" | "Q" | "9" | "+") ...], 
   b = If[# > 0, ToString@#, "No"] <> " bottle" <> 
      If[# == 1, "", "s"] <> " of beer" &; 
   w = b@# <> " on the wall" &; 
   Print /@ 
    StringCases[#, {"H" -> "Hello, world!", "Q" -> #, 
      "9" -> "" <> 
        Table[w@n <> ",\n" <> b@n <> 
          ".\ntake one down, pass it around,\n" <> w[n - 1] <> 
          If[n == 1, ".", ".\n\n"], {n, 99, 1, -1}]}];, 
   "Source code contains invalid characters"] &
alephalpha
источник
Очень впечатляет, но, похоже, есть небольшие ошибки. '[Q]] выводит "Q". h ["9"] работает, но h [9] выводит всю программу (я не понимаю как.)
DavidC
@DavidCarraher Это выводит код из-за того, как StringMatchQ и If терпят неудачу:If[StringMatchQ[3, "a"], x, y]
ssch
6

C 599 587 487 481 467 символов

Я уверен, что это можно победить. Я использую C в конце концов. Есть причина, по которой вы не видите много выигрышных записей о гольфе, написанных на C. Это теперь 467 символов благодаря преступному злоупотреблению #define.

Укажите исходный файл HQ9 + в качестве аргумента командной строки.

РЕДАКТИРОВАТЬ: теперь принимает источник из стандартного ввода, а не файл. Запустите программу, начните вводить код, CTRL- Cкогда закончите, чтобы запустить ее.

Он компилируется как минимум в MinGW / GCC с: gcc -o hq9+.exe hq9+.c

Должно работать в MSVC, но я не хотел создавать целое решение только для этого. :)

#define B "bottles of beer"
#define C case
#define P printf
#define R break
a,i,j,s;
main(){
char p[9999],c;
for(;;) {
    switch(c=getch()){
    C 'H':C 'Q':C '9':C '+': C 3: R;
    default:P("Source code contains invalid characters\n");
    }
    if (c==3) R;
    p[s++]=c;
}
for(i=0;i<s;i++){
    c = p[i];
    switch(c){
    C 'H':
        P("Hello world!");
        R;
    C 'Q':
        for(j=0;j<s;j++)putchar(p[j]);
        R;
    C '9':
        j=99;
        while(j){
            P("%d "B" on the wall,\n%d "B".\nTake one down, pass it around,\n%d "B".\n",j,j,j-1);
            j--;
        }
        R;
    C '+':
        a++;
    }
}
}

Или:

#define B "bottles of beer"
#define C case
#define P printf
#define R break
a,i,j,s;main(){char p[9999],c;for(;;){switch(c=getch()){C 'H':C 'Q':C '9':C '+': C 3: R;default:P("Source code contains invalid characters\n");}if (c==3) R;p[s++]=c;}for(i=0;i<s;i++){c = p[i];switch(c){C 'H':P("Hello world!");R;C 'Q':for(j=0;j<s;j++)putchar(p[j]);R;C '9':j=99;while(j){P("%d "B" on the wall,\n%d "B".\nTake one down, pass it around,\n%d "B".\n",j,j,j-1);j--;}R;C '+':a++;}}}
Майк С
источник
Получил до 487 символов, используя stdin вместо файла для ввода.
Майк C
Сделайте это 464, злоупотребляя #define.
Майк C
Вы можете избавиться от пробелов, как те, что после Cи пару раньше R;. Можно также сбрить 8 символов с p[s++]=0;после цикла ввода, чтобы упростить печать p.
Даниэль Любаров
3

Python 2 - 452 453 443 байта

q=raw_input()
if set(q)-set('HQ9+'):print'Source code contains invalid characters'
b=' bottles of beer'
b=[b,b.replace('s','')]
w=[a+' on the wall'for a in b]
t='Take one down, pass it around,\n'
c={'H':'Hello, world!','Q':q,'9':''.join(`i`+w[i<2]+',\n'+`i`+b[i<2]+'.\n'+t+(`i`if i>1 else'No')+w[0]+'.\n'for i in range(1,100)[::-1])+'No'+w[0]+',\nNo'+b[0]+'.\n'+'Go to the store, buy some more,\n99'+w[0]+'.'}
for d in q:
 if d in c:print c[d]

BLEH. Это было уже плохо, но потом я обнаружил ошибку, которая стоила мне одного байта, чтобы ее исправить. BLEH.

(Раньше я не включал +в вывод для Q. Вход Q+++дал Q, например, выход .)

Спасли некоторые символы, не выходя при неверном вводе, как я и думал.

Разъясненная версия в ближайшее время.Я сдался. Я едва понимаю, как работает это чудовище. Если есть спрос, я сделаю еще один шаг, но пока этого не произойдет.

undergroundmonorail
источник
Вы не exitиспользуете недопустимый символ, просто отображаете сообщение, чтобы вы могли сохранить там 7 символов.
Кайл Канос
@KyleKanos О, я неправильно это понял. Благодарность!
подземный
Ваша лирика не правильная - в настоящее время она говорит: 99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around, *99* bottles of beer on the wall. он должен сказать: 99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around, *98* bottles of beer on the wall.
Оливер Ни
Это также дает ошибку, когда я вхожу +. Вы должны игнорировать + , а не давать ошибку
Оливер Ни
Также не должно быть ничего между выходами. Например, если я вхожу, HQHHнадо сказатьHello World!HQHHHelloWorld!Hello World!
Оливер Ни
3

Perl, 325 - 8 = 317

sub p{print@_}$_=<>;$a=' on the wall';$b=' bottle';$e=' of beer';$c='Take one down, pass it around';if(!/^[hqHQ9+]+$/){p"Source code contains invalid characters";exit}$k=$_;for(/./g){/H|h/&&p"Hello, World!";if(/9/){$i=99;$d=$b."s$e";while($i>0){p"$i$d$a
$i$d
$c
";$q=--$i==1?'':'s';$d="$b$q$e";$i||=No;p"$i$d$a
"}}/Q|q/&&p$k}

Expanded:

sub p{print@_}
$_=<>;
$a=' on the wall';
$b=' bottle';
$e=' of beer';
$c='Take one down, pass it around';
if(!/^[hqHQ9+]+$/){
    p"Source code contains invalid characters";
    exit
}
$k=$_;
for(/./g){
    /H|h/&&p"Hello, World!";
    if(/9/){
        $i=99;
        $d=$b."s$e";
        while($i>0){
            p"$i$d$a
$i$d
$c
";
            $q=--$i==1?'':'s';
            $d="$b$q$e";
            $i||=No;
            p"$i$d$a
"
        }
    }
    /Q|q/&&p$k
}
faubi
источник
2

Рубин, 364 360 - 8 = 352

Все еще есть много возможностей для улучшения. Код 99 бутылок, украденный отсюда .

p=gets.upcase
if p=~/[^HQ9+
]/
puts"Source code contains invalid characters"else
p.each_char{|x|case x
when ?H
puts"Hello, world!"
when ?Q
puts p
when ?9
def c;"#{$n} bottle#{'s'if$n>1} of beer on the wall"end
($n=99).times{puts"#{c}, #{c[0..-13]}.
#{$n<2?"Go to the store and buy some more":"Take one down and pass it around"}, #{$n=($n-2)%99+1;c}.

"}end}end
Дверная ручка
источник
Там должно быть No more bottles of beer on the wallпосле 1 bottleраздела. тогда этоGo to the store...
Оливер Ни
1 bottle of beer on the wall, 1 bottle of beer on the wall, take one down, pass it around, no more bottles of beer on the wall. No more bottles of beer on the wall, no more bottles of beer, go to the store, buy some more, 99 bottles of beer on the wall.
Оливер Ни
@ Оливер Вопрос не определяет точную лирику песни. Ни в каком месте это не требует, чтобы раздел "больше" не был включен.
Ручка двери
Хорошо, но также не должно быть новой строки между выходами.
Оливер Ни
@ Оливер Где проблема говорит это?
Ручка двери
2

Хаскелл, 298

main=interact g
g s|all(`elem`"HQ9+")s=s>>=(%s)|0<1="Source code contains invalid characters"
'H'%_="hello World!"
'Q'%s=s
'9'%_=drop 32$d 99
_%_=""
k=" bottles of beer on the wall"
d 0="No more"++k++"."
d n|a<-shows n k=[a,".\n\n",a,",\n",take 18a,".\ntake one down, pass it around\n",d$n-1]>>=id

это довольно просто. %возвращает вывод команды (учитывая исходный код для использования Q). dпо соображениям игры в гольф возвращает песню «99 бутылок» с ненужной строкой. все обернуто в интерактив (вы можете использовать gвместо mainтестирования)

гордый хаскеллер
источник
Как мне его запустить? Я пытался вставить его в WinGHCi, но я получаю <interactive>:8:5: parse error on input ‘=’.
ProgramFOX
@ProgramFOX я понятия не имею ... я проверю, когда смогу
гордый haskeller
@ProgramFOX извините, это заняло много времени :-). вы не используете GHCi должным образом. в GHCi вы не можете напрямую вводить определения, так как они ожидают выражения. Вы можете использовать a letдля вставки определений (это разрывается при вставке нескольких определений, не разделенных ;) или запустить код из файла.
гордый haskeller
Понимаю. Я все еще терплю неудачу в попытке запустить это все же; когда я загружаю файл и вызываю main, он говорит, что исходный код содержит недопустимые символы, когда я пытаюсь выполнить H. Когда я пытаюсь запустить gвместо main, он сразу выдает ошибку.
ProgramFOX
@ProgramFOX mainне работает, потому что добавленная новая строка не является допустимой командой. Вот почему я рекомендовал использовать gвместо этого. Что касается g, putStrLn $ g "H" не работает должным образом?
гордый haskeller
2

J - 444 байта

Номер мне понравился, поэтому перестал играть в гольф. Вот, пожалуйста, функция с одним выражением!

f=:'Source code contains invalid characters'"_`('Hello, world!'"_`[`((((s=:(<:@[s],L,(v,LF,'Take one down and pass it around, '"_,b@<:,' of beer on the wall.'"_)@[,''"_)`(],(L=:LF,LF),(v=:1&b,' of beer on the wall, '"_,b,' of beer.'"_)@[)@.([<1:))''"_),LF,'Go to the store and buy some more, '"_,(b=:({&'Nn'@([=0:),'o more'"_)`(":@])@.(]>0:),{.&' bottles'@(8:-=&1@])),' of beer on the wall.'"_)@(99"_))`]@.('HQ9+'&i.@])"0 1 0])@.(*./@e.&'HQ9+')

Примеры:

   hq9 '9QHHQ+'
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.

98 bottles of beer on the wall, 98 bottles of beer.
Take one down and pass it around, 97 bottles of beer on the wall.

...

3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.

2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.

1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.

No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
9QHHQ+
Hello, world!
Hello, world!
9QHHQ+
+
   hq9 '9QHHaQ'
Source code contains invalid characters
seequ
источник
И нет, я не буду писать объяснение этому. Слишком долго.
Seequ
Подожди, почему за это проголосовали?
seequ
2

Фортран 528 470 481

Требуется компиляция с -fppфлагом (+3 для оценки) 1, чтобы использовать директивы предварительной обработки (что экономит более 3 символов, так что я полностью согласен с этим). Это также нечувствительно к регистру, так что есть -8: D. Сохранено 5 символов, так как они не были предварительно обработаны endifтак, как это используется один раз .

Требует, чтобы файл имел .F90расширение (имеет смысл называть его hq9+.F90), чтобы компилятор принудительно выполнял предварительную обработку. Код чувствителен к регистру; добавление без учета регистра добавляет что-то вроде 16 символов, так что экономить 8 символов не стоит. Мой предыдущий ответ не учитывал изменение множественного числа в bottlesfor 9; эта версия исправляет это (и, к сожалению, добавляет гораздо больше символов).

#define P print*,
#define W " of beer on the wall"
#define N print'(x,i0,a,a)',
#define e enddo
#define S case
#define J len(trim(c))
character(len=99)::c,b=" bottles";read*,c;do i=1,J;if(all(c(i:i)/=["H","Q",'9',"+"])) then;P"Source code contains invalid characters";exit;endif;e;do i=1,J;select S(c(i:i));S("H");P"Hello, world!";S("Q");P c;S("9");l=8;do k=99,1,-1;N k,b(1:l),W;N k,b(1:l)," of beer";P "Take one down, pass it around";if(k==2)l=l-1;if(k==1)exit;N k-1,b(1:l),W;P"";e;P"No more",trim(b),W;S default;endselect;e;end

Выглядит намного лучше, если не обрабатывать и не обрабатывать (возможно, потому что вы можете видеть, что происходит):

program hq9
   character(len=99)::c,b=" bottles"
   read*,c
   do i=1,len(trim(c))
! change the below to ["H","h","Q","q","9","+"] to be case-insensitive
      if(all(c(i:i)/=["H","Q","9","+"]))then
         print*,"Source code contains invalid characters"
         exit
      endif
   enddo
   do i=1,len(trim(c))
      select case(c(i:i))
        case("H")                ! change to case("H","h") for case-insensitive
           print*,"Hello, world!"
        case("Q")                ! change to case("Q","q") for case-insensitive
           print*, c
        case("9")
           l=8
           do k=99,1,-1
              print'(x,i0,a,a)', k,b(1:l)," of beer on the wall"
              print'(x,i0,a)', k,b(1:l)," of beer"
              print*,"Take one down, pass it around"
              if(k==2) l=l-1
              if(k==1) exit
              print'(x,i0,a)', k-1,b(1:l)," of beer on the wall"
              print*,""
           enddo
           print*,"No more",trim(b)," of beer on the wall"
        case default
           ! do nothing
      endselect
   enddo
end program hq9
Кайл Канос
источник
Я думаю, что приемлемо требовать определенного расширения, чтобы компилятор знал, что он компилирует. Аналогом может быть требование именования файла C ++, .ccчтобы не нуждался в -lstdc++флаге.
Примо
2

Python 2, 340 - 8 = 332

s,o=raw_input(),''
for z in s:
 if z in'Hh':o+='Hello World!'
 elif z in'Qq':o+=s
 elif'9'==z:
  i=298
  while~-i:print i/3or 99,'bottle'+'s of beer on the wall.\n'[2<i<6:9+i%3*12]+'..\nGToa kteo  otnhee  dsotwonr,e ,p absusy  isto maer omuonrde,,'[(i>3)+i%3*68::2];i-=1
 elif'+'!=z:o='Source code contains invalid characters';break
print o
Оливер Ни
источник
1

Луа 443 - 8 = 435 464 - 8 = 456

Мне удалось сохранить 21 символ, используя несколько if-ends вместо if-elseif-end. У меня также было несколько лишних пробелов, плавающих вокруг после нескольких ).

p=print o=" of beer"t=" on the wall"B=" bottle"b=" bottles"l=io.read("*l");g=l:lower()if g:match"[^hq9+]"then p("Source code contains invalid characters")end for i=1,#g do s=g:sub(i,i)if s=='h'then p("Hello, world")end if s=='q'then p(l)end if s=='9'then n=99 repeat p(n..b..o..t..", "..n..b..o)n=n-1 p("Take one down, pass it around, "..n..b..o..t..".")p()until n==1 p("1"..B..o..t..", 1"..B..o)p("No more"..b..o..t..", no more"..b..o)end end

Я довольно доволен этим, хотя он не намного короче, чем мой ответ на Фортране . Код 99 бутылок пива был изменен из этого ответа Алессандро . У нас нет

-- reuse stuff
p=print
o=" of beer"
t=" on the wall"
B=" bottle"
b=" bottles"
-- read the line & then lowercase it for case insensitivity
l=io.read("*l");g=l:lower()
if g:match"[^hq9+]" then -- horray for basic regex
   p("Source code contains invalid characters")
end
for i=1,#g do
   s=g:sub(i,i)               -- take substring
   if s=='h' then p("Hello, world") end
   if s=='q' then p(l) end
   if s=='9' then
      n=99
      repeat
         p(n..b..o..t..", "..n..b..o)
         n=n-1
         p("Take one down, pass it around, "..n..b..o..t..".")
         p()
      until n==1
      p("1"..B..o..t..", 1"..B..o)
      p("No more"..b..o..t..", no more"..b..o)
   end
end
Кайл Канос
источник
Код для ввода строчных букв стоит 12 символов, поэтому бонус не стоит.
nyuszika7h
Вам не нужно вводить строчные буквы, вы можете просто сделать что-то вродеif s in'Hh'
Оливер Ni
Это экономит 8 символов
Оливер Ни
@MCParadox: Э-э, это тот Python, о котором вы думаете, Lua inпредназначен для итераторов цикла for, а не для сравнения; вы получите ошибку, если вы вставите это туда. Здесь есть три варианта: (1) использовать matchв каждой строке, (2) пользователь s=='h'or s=='H'в каждой строке, (3) сделать так, как я это сделал. Ясно, что (3) короче (1) и (2).
Кайл Канос
1

Юлия, 362

s = chomp(readline(STDIN))
l=""
z=" of beer"
q,r,w,t=" bottles$z"," bottle$z"," on the wall.\n","take one down, pass it around,\n"
for j=99:-1:2
b="$j$q"
l*="$b$w$b.\n$t"
end
l*="1$r$(w)1$r.\n$(t)No$q$w"
p=println
all(c->c in "HQ9+", s)||p("Source code contains invalid characters")
for c in s
    c=='Q'&&p(s)
    c=='H'&&p("Hello, world!")
    c=='9'&&p(l)
end
GGGG
источник
1

Tcl, 515

set d [read stdin]
if {![regexp {^[hq9\+HQ]*$} $d]} {puts "Source code contains invalid characters"}
lmap c [split $d {}] {set b { bottles of beer}
switch -- $c H {puts "Hello, world"} Q {puts $d} 9 {for {set i 99} {$i>2} {incr i -1} {puts "$i$b on the wall,
$i$b.
Take one down, pass it around,
[expr $i-1]$b on the wall.
"}
puts "2$b on the wall,
2$b.
Take one down, pass it around,
1 bottle of beer on the wall.

1 bottle of beer on the wall,
1 bottle of beer.
Take one down, pass it around,
No$b on the wall."}}

Просто немного в гольфе, все еще меньше, чем C, и правильные 99 бутылок пива заканчиваются стихами.

Йоханнес Кун
источник
Хорошо, теперь это законно. Хорошая работа, ты победил меня. Я должен прекратить использовать C для гольфа.
Майк C
Вы можете удалить первую строку и вставить ее в последний параметр regexp. Вы можете получить мой гольф из 99 сортов пива на codegolf.stackexchange.com/a/109818/29325
sergiol
1

JavaScript (ES6), 385

s=>{n=99,b=' bottle',j=' of beer',d=' on the wall',e='Take one down, pass it around',k='Go to the store, buy some more',l='No',o='s',f=', ';for(i=s.split(m=v='');~n;)v+=[n||l,b,n-1?o:m,j,d,f,n||l,b,n-1?o:m,j,f,n?e:k,f,--n<1?99:n,b,n-1?o:m,j,d,'! '].join(m);return s.match(/[^HQ9\+]/,r='')?'Source code contains invalid characters':[...s].map(c=>({H:'Hello World!',9:v,Q:s})[c]).join``}

Не выбирать без учета регистра, стоило бы слишком много символов. Даже близко не к некоторым другим записям, но, тем не менее, было весело!

JavaScript, 344

Я сделал версию с менее полной версией песни:

(function(i){if(s.match(/[^HQ9\+]/)){m='Source code contains invalid characters'}else{n=99,b=' bottles of beer ',d='on the wall',e='take one down, pass it around',f=', ';for(;n;)v+=[n,b,d,f,n,b,f,e,f,--n||'no more',b,d,'! '].join(m);h={H:'Hello World!',Q:arguments.callee+m,9:v};for(;c=i[n++];)m+=h[c]||''}alert(m)})((s=prompt()).split(m=v=''))

но, увидев другие записи (и посмотрев текст песни, который знал!), я подумал, что это что-то вроде полицейского!

Дом Гастингс
источник
Должно быть Go to the store, buy some more, *99* bottles of beer on the wall, нет*No more* bottles of beer on the wall
Оливер Ни
Если вы купите еще, как еще не может быть?
Оливер Ни
А также, Qне работает для меня.
Оливер Ни
@ Оливер не заметил, что вы прокомментировали это тогда ... Я совершенно не понял, когда Qпредполагалось сделать это время и предоставил исходный код функции вместо ввода ... Это было изначально моей причиной для этого в JS эта часть была бы легкой, однако теперь я знаю, что это совсем не то, что требуется!
Дом Гастингс
@Oliver обновил текст песни!
Дом Гастингс
1

C 562 байта

char*c="%1d %3$s of %4$s on the %5$s, %1d %3$s of %4$s.\n\0Take one down and pass it around, %2d %3$s of %4$s on the %5$s.\n\0Go to the store and buy some more, %1d %3$s of %4$s on the %5$s.\n";main(int a,char**b){int x=0;for(int i=0;i<strlen(b[1]);i++){if(b[1][i]=='+')x++;else if(b[1][i]=='9'){int k=99;while(1){printf(&c[0],k,k,k==1?"bottle":"bottles","beer","wall");if(k!=1){printf(&c[49],k,k,"bottles","beer","wall");k--;}else{k=99;printf(&c[114],k,k,"bottles","beer","wall");break;}}}else printf("%s",b[1][i]=='H'?"Hello, world!":(b[1][i]=='Q'?b[1]:""));}}

Как полная программа. Первый аргумент - это программа HQ9 +. С реальным аккумулятором. Я бросил вызов себе, чтобы не использовать определения утверждений.

Безголовая версия:

char* c = "%1d %3$s of %4$s on the %5$s, %1d %3$s of %4$s.\n\0Take one down and pass it around, %2d %3$s of %4$s on the %5$s.\n\0Go to the store and buy some more, %1d %3$s of %4$s on the %5$s.\n";
main (int a, char** b) {
    int x = 0;
    for (int i = 0; i < strlen(b[1]); i++) {
        if (b[1][i] == '+')
            x++;
        else if (b[1][i] == '9') {
            int k = 99;
            while (1) {
                printf(&c[0], k, k, k == 1 ? "bottle" : "bottles", "beer", "wall");
                if (k != 1) {
                    printf(&c[49], k, k, "bottles", "beer", "wall");
                    k--;
                } else {
                    k=99;
                    printf(&c[114], k, k, "bottles", "beer", "wall");
                    break;
                }
            }
        } else
            printf("%s",b[1][i] == 'H' ? "Hello, world!" : (b[1][i] == 'Q' ? b[1] : ""));
    }
}
печенье
источник
0

Java, 546 байт

Это моя первая подача кода в гольф. Я уверен, что мы могли бы сделать больше с этим. Он читает входные данные как аргумент командной строки. Пивной кодекс "позаимствован" из java ответа "99 бутылок пива" (креативное достояние)

class a{public static void main(String[] a){if(a[0].matches("^[HQ9\\Q+\\E]+$")){for(char c:a[0].toCharArray()){if(c=='H')p("Hello, world!");if(c=='Q')p(a[0]);if(c=='9')b();}}else{System.out.println("Source code contains invalid characters");}}static void p(String s){System.out.println(s);}static void b(){String b=" of beer",c=" on the wall",n=".\n",s;for(int i=100;i-->1;){s=" bottle"+(i>1?"s":"");p(i+s+b+c+", "+i+s+b+n+(i<2?"Go to the store and buy some more, 99":"Take one down and pass it around, "+(i-1))+" bottle"+(i!=2?"s":"")+b+c+n);}}}

Дайте мне знать, если аргументы командной строки не приемлемы. Это было очень весело!

Рохан Джунджхунвала
источник
CLA в порядке. Хороший ответ.
Rɪᴋᴇʀ
0

Excel VBA, 489 байт

отступ:

Sub h(s)
For c=1 To Len(s)
Select Case Mid(s,c,1)
Case "H"
Debug.? "Hello,World!"
Case "Q"
Set v=ActiveWorkbook.VBProject.VBComponents("M").CodeModule:For n=1 To v.countoflines:Debug.? v.Lines(n,1):Next
Case "+"
a=a+1
Case "9"
s=" Bottles of Beer":o=" Bottle of Beer":w=" on the wall":t=". Take 1 down pass it around,":p=",":d=".":For n=99 To 3 Step -1:Debug.? n;s;w;p;n;s;t;n-1;s;w;d:Next:Debug.? 2;s;w;p;2;s;t;1;o;w;d:Debug.? 1;o;w;p;1;o;t;"No";s;w;d
End Select
Next
End Sub

(отступ для удобства чтения)

Sub h(s)
For c=1 To Len(s)
Select Case Mid(s,c,1)
    Case "H"
        Debug.? "Hello,World!"
    Case "Q"
        Set v=ActiveWorkbook.VBProject.VBComponents("M").CodeModule
        For n=1 To v.countoflines
            Debug.? v.Lines(n,1)
        Next
    Case "+"
        a=a+1
    Case "9"
        s=" Bottles of Beer"
        o=" Bottle of Beer"
        w=" on the wall"
        t=". Take 1 down pass it around,"
        p=","
        d="."
        For n=99 To 3 Step -1
            Debug.? n;s;w;p;n;s;t;n-1;s;w;d
        Next
        Debug.? 2;s;w;p;2;s;t;1;o;w;d
        Debug.? 1;o;w;p;1;o;t;"No";s;w;d
End Select
Next
End Sub

Переименуйте стандартный вызов Module1 в M
с помощью. h "+++++++++Your Code"
Это также будет работать в других офисных приложениях, изменяя ActiveWorkbook на соответствующий тип документа.

SeanC
источник
обратите внимание, что Excel добавит пробелы и расширит аббревиатуры, поэтому в Excel код состоит из 531
символа
То 636 персонажей
Оливер Ни
Удалите все пробелы из моего отступа, @oliver
SeanC
Вы можете потерять 3 байта, преобразовав все экземпляры For n=1 Toв For n=1To(удаление пробелов до To) и 4 байта, преобразовав все экземпляры Debug.? 2;в Debug.?2;(удаление пробелов после ?ключевого слова)
Тейлор Скотт,