Создать компилятор FizzBuzz


17

Добро пожаловать в мир компилятора гольфа. Ваша задача - написать программу, которая генерирует другую программу для воспроизведения варианта FizzBuzz по спецификации.

Ваш компилятор

Напишите компилятор, который генерирует варианты программы FizzBuzz для спецификации. Спецификация этого варианта выражается в виде массива пар целое число / строка.

  • Ввод может быть в любой форме, удобной для вашего языка. (Мои примеры используют n: xxxx, но это только для иллюстративных целей.)
  • Каждый целочисленный ввод может использоваться только один раз за вызов вашего компилятора.
  • Целое число каждой пары будет иметь значение не менее одного.
  • Строка каждой пары будет состоять только из четырех букв ASCII.
  • Выходные данные должны быть единой законченной программой, которая соответствует приведенным ниже правилам.
  • Вывод может быть в любой удобной форме, если это текстовая программа. (Так что нет возврата лямбда-выражений.)

Поведение не определено для входных данных, не соответствующих вышеуказанным правилам.

Ваша сгенерированная программа FizzBuzz

Программа, сгенерированная вашим компилятором, примет одно целое число n в качестве входных данных. Он выведет последовательность чисел, начиная с одного до n включительно , заменяя числа строками FizzBuzz при необходимости.

  • Сгенерированная программа должна быть на том же языке, что и компилятор.
  • Ввод n может быть в любой форме, удобной для вашего языка.
  • n будет иметь значение по крайней мере один.
  • Число, кратное хотя бы одному из целых чисел, введенных в компилятор, должно быть заменено всеми строками в паре с этими целыми числами, соединенными вместе.
  • Число, которое не должно заменяться строкой FizzBuzz, должно быть выведено в десятичном формате ASCII.

Например;

> GenFizzBuzz 3:Fizz 5:Buzz
> a.out 5
1
2
Fizz
4
Buzz

счет

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

  1. Просто посчитай. (Нет входных данных - сгенерированная программа будет считать от 1 до n без замен.)
  2. Просто Гольф. (1: Golf - сгенерированная программа выдаст «Golf» n раз.)
  3. Классический FizzBuzz. (3: Fizz, 5: Buzz)

(Обратите внимание, что ваш компилятор должен генерировать код для любого допустимого ввода, а не только перечисленных.)


нет выигрыша по длине компилятора ??
Спарр

мы можем предположить, что целые числа являются одной цифрой? что в строках нет пробелов?
Спарр

@Sparr Будет ли это (двузначные целые числа) иметь значение? Помните, что только ваш код генерирует ваш счет.
billpg

Что ж, fizzbuzz - это уже чрезвычайно сложная проблема в других местах в Интернете. Я не знаю, смогу ли я забыть прочитать решение, если попробую.
Спарр

1
Наконец, задача для гольфа, которая действительно имеет смысл писать в AWK.
Shadowtalker

Ответы:


8

Python 3 - 168 162 + 230 = 392

О, Питон, ты так стараешься, но умножение import sys;sys.argvматериала на 4 действительно больно!

import sys;a=eval(sys.argv[1])
print("import sys\nfor i in range(1,int(sys.argv[1])+1):print("+"+".join('"%s"*(i%%%d==0)'%t for t in a)+(a and"or str(i))"or"i)"))

Выходные программы:

import sys
for i in range(1,int(sys.argv[1])+1):print(i)
import sys
for i in range(1,int(sys.argv[1])+1):print("Golf"*(i%1==0)or str(i))
import sys
for i in range(1,int(sys.argv[1])+1):print("Fizz"*(i%3==0)+"Buzz"*(i%5==0)or str(i))
  • Ожидаемый ввод для основной программы представляет собой доступную для последовательности последовательность кортежей Python или '()'не требует ввода. (Вы действительно сказать , «удобно».) Пример ввода: '()', '("Golf",1),','("Fizz",3),("Buzz",5)' примечание со ссылкой на оболочке и задней запятой на один вход.

  • Исправлена ​​ошибка с 1:00, когда переход от dict (неопределенный порядок!) К кортежам.

  • Ожидаемый вклад для других программ - это просто число


В вашем примере аргумента командной строки я должен был заключить в двойные кавычки и использовать одинарные кавычки для 'Fizz' и 'Buzz' - как, например, `" {3: 'Fizz', 5: 'Buzz'} ", однако программа по-прежнему выкидываю ошибку для меня.
Джеймс Уильямс

В чем ошибка?
Джейсон С

@JasonS - Привет. Я заинтересован в вашем опыте этого вызова. meta.codegolf.stackexchange.com/questions/5050/…
billpg

6

perl6 376 340 84 + 115 = 199

ОБНОВЛЕНИЕ: переключено с perl5 на perl6, чтобы получить say без use feature.

ОБНОВЛЕНИЕ: три теста вместо пяти

Для FizzBuzz существуют сотни уже готовых решений, и многие конкурсы заканчиваются тем же результатом, поэтому я и начал. Мой компилятор только производит настроенную версию этого решения. Несколько дополнительных символов были вставлены, чтобы учесть вариант «просто считать».

компилятор, ожидает аргументы вроде так: "Fizz 3" "Buzz 5"

print'say(('.(join'.',map{'('.(join')[$_%',split).']'}@ARGV).')||$_)for 1..$ARGV[0]'

скомпилированные программы, ожидайте аргумент так: 100

say(()||$_)for 1..$ARGV[0]
say(((Golf)[$_%1])||$_)for 1..$ARGV[0]
say(((Fizz)[$_%3].(Buzz)[$_%5])||$_)for 1..$ARGV[0]

скомпилированные программы для старых тестовых случаев:

say(((Twoo)[$_%2].(Four)[$_%4].(Eiht)[$_%8])||$_)for 1..$ARGV[0]
say(((Twoo)[$_%2].(Thre)[$_%3].(Five)[$_%5].(Sevn)[$_%7])||$_)for 1..$ARGV[0]

Я изменил правила, как обсуждалось в комментариях к вопросу. Вы хотите пересчитать свой счет.
billpg

@billpg сделано, и улучшено :)
Спарр

Всем привет. Я заинтересован в вашем опыте этого вызова. meta.codegolf.stackexchange.com/questions/5050/…
billpg

3

Pyth - 51 + (38 + 43 + 50) = 182 байта

Вероятно, может сыграть в компиляторе несколько байт. Ссылки на все из них являются постоянными ссылками на онлайн-переводчика.

Компилятор - 51 байт

%"K[%s)=dc\"%s\"dFGr1hQJkFNKI!%%GN~J@dxKN))?JJG",zw

Просто выполняет форматирование строки с входным кортежем. Принимает входные данные, как:

3 5
Fizz Buzz

Ничего - 38 байт

K[)=dc""dFGr1hQJkFNKI!%GN~J@dxKN))?JJG

Просто Гольф - 43 байта

K[1)=dc"Golf"dFGr1hQJkFNKI!%GN~J@dxKN))?JJG

Классический Fizz Buzz - 50 байтов

K[3 5)=dc"Fizz Buzz"dFGr1hQJkFNKI!%GN~J@dxKN))?JJG

2

С ++ 11 ~ 486 + (234 + 244 + 255) = 1219

Первое участие здесь, это испытание не является одним из самых сложных, поэтому я решил попробовать. Используя C ++, хотя и с дополнениями C ++ 11, это все еще довольно многословный язык, но я уверен, что есть возможности для улучшения.

Компилятор (486):

#include<sstream>
#include<iostream>
using namespace std;main(int c,char**v){stringstream t;int i;string s,o;o="#include <iostream>\n#include <map>\nusing namespace std;main(int c,char**v){int i,n=stoi(v[1]);map<int,string> f{";int z=2;for(int j=1;j<c;++j){t.str(v[j]);t.clear();t >> i; t >> s;o+="{"+to_string(i)+",\""+s+"\"}"+(z++==c?"":",");}o+= R"(};bool p;for(i=1;i<n;++i){p=true;for(auto e:f){if(i%e.first==0){cout<<e.second;p=false;}}cout<<(p?to_string(i):"")+"\n";}})";cout<<o;}

Предполагает аргументы в виде 3Fizz 5Buzz и т. Д.

Количество (234):

#include <iostream>
#include <map>
using namespace std;main(int c,char**v){int i,n=stoi(v[1]);map<int,string> f{};bool p;for(i=1;i<n;++i){p=true;for(auto e:f){if(i%e.first==0){cout<<e.second;p=false;}}cout<<(p?to_string(i):"")+"\n";}}

Гольф (244):

#include <iostream>
#include <map>
using namespace std;main(int c,char**v){int i,n=stoi(v[1]);map<int,string> f{{1,"Golf"}};bool p;for(i=1;i<n;++i){p=true;for(auto e:f){if(i%e.first==0){cout<<e.second;p=false;}}cout<<(p?to_string(i):"")+"\n";}}

FizzBuzz (255):

#include <iostream>
#include <map>
using namespace std;main(int c,char**v){int i,n=stoi(v[1]);map<int,string> f{{3,"Fizz"},{5,"Buzz"}};bool p;for(i=1;i<n;++i){p=true;for(auto e:f){if(i%e.first==0){cout<<e.second;p=false;}}cout<<(p?to_string(i):"")+"\n";}}

Дополнительная информация

Протестировано с GCC 4.8.1, никаких читов компилятора.

Вот небольшой make-файл для автоматизации генерации тестовых случаев и их запуска (use make run):

run:
    g++ main.cpp --std=c++11 -o fbc

    ./fbc > count.cpp
    g++ count.cpp --std=c++11
    echo "======= Count ========"
    ./a.out 15

    ./fbc 1Golf > golf.cpp
    g++ golf.cpp --std=c++11
    echo "======= Golf ========"
    ./a.out 15

    ./fbc 3Fizz 5Buzz > fizzbuzz.cpp
    g++ fizzbuzz.cpp --std=c++11
    echo "======= FizzBuzz ========"
    ./a.out 15

Всем привет. Я заинтересован в вашем опыте этого вызова. meta.codegolf.stackexchange.com/questions/5050/…
billpg

map<int,string> fможет быть map<int,string>f. Вы можете инициализировать j=1одновременно с z.
Yytsi

2

Рубин 99 + (86 + 94 + 103) = 382

puts"(1..ARGV[0].to_i).each{|i|x=[];#{ARGV[0]}.each{|k,v|x<<v if i%k==0};puts x.size>0?x.join():i}"

Использование:

wc -c main.rb # 99 chars
ruby main.rb "{}" | ruby - 100 # 1..2..3..
ruby main.rb "{}" | wc -c # 86 chars
ruby main.rb "{1=>:Golf}" | ruby - 100 # Golf..Golf..Golf..
ruby main.rb "{1=>:Golf}" | wc -c # 94 chars
ruby main.rb "{3=>:Fizz,5=>:Buzz}" | ruby - 100 # 1..2..Fizz..4..Buzz..
ruby main.rb "{3=>:Fizz,5=>:Buzz}" | wc -c # 103 chars

2

Stax , 23 + 5 + 17 + 29 = 74

╥╟.└ç╘SJ∞CF╔v=▌╝Σ@∞ìé«g

Запустите и отладьте его

Самый короткий ответ до сих пор Не удивительно побежден Желе. Шаблон строки, представленный в Stax, действительно аккуратный и предоставляет функции, похожие на printf. Программы, сгенерированные компилятором, почти всегда настолько коротки, насколько лучше всего можно достичь, вручную набирая код без использования упаковки.

Сам компилятор составляет 23 байта длину .

Эквивалент ASCII:

{H34|S_h"_`c%z`n?+"m"mz`cc_?

При условии ввода [], генерирует этот (5 байтов)

mzc_?

Запустите и отладьте его

При условии ввода [[1,"Golf"]], генерирует этот (17 байт)

mz_1%z"Golf"?+c_?

Запустите и отладьте его

При условии ввода [[3,"Fizz"],[5,"Buzz"]], генерирует этот (29 байт)

mz_3%z"Fizz"?+_5%z"Buzz"?+c_?

Запустите и отладьте его


1

Обыкновенный Лисп, 636 577

(ql:quickload'cl-ppcre)(lambda(z)(princ(subseq(ppcre:regex-replace-all" *([(')]) *"(with-output-to-string(@)(print`(lambda(n)(dotimes(i n)(loop for(m s)in ',z if(=(mod(1+ i)m)0)do(princ s))(do()((fresh-line))(princ (1+ i)))))@))"\\1")1)))

Я взял другой ответ и обернул его в кавычки при добавлении входных параметров. Я печатаю полученную форму в виде одной строки и удаляю ненужные пробельные символы. Компилятор немного длиннее предыдущей версии, но итоговая оценка снижается.

Гол

(let ((*standard-output* (make-broadcast-stream)))
  (loop
     for form in '(215                      ; Compiler
                   ()                       ; Count
                   ((1 "Golf"))             ; Golf
                   ((3 "Fizz")(5 "Buzz")))  ; FizzBuzz
     for length = (if (numberp form) form
                      (length (funcall *fun* form)))
     collect length into lengths
     sum length into sum
     finally (return (values sum lengths))))

Возвращаемые значения:

574
(215 111 119 129)

милая

(defun fizz-buzz-compiler (z)
  (princ (subseq
          (cl-ppcre:regex-replace-all
           " *([(')]) *"
           (with-output-to-string (stream)
             (print
              `(lambda (n)
                 (dotimes(i n)
                   (loop for (m s) in ',z
                      if (=(mod(1+ i)m)0)
                      do (princ s))
                   (do () ((fresh-line))
                     (princ (1+ i))))) stream))
             "\\1") 1)))

Формат ввода представляет собой список (number string)пар. Например:

(fizz-buzz-compiler '((3 "Fizz")(5 "Buzz")))

... печатает на стандартный вывод:

(LAMBDA(N)(DOTIMES(I N)(LOOP FOR(M S)IN'((3 "Fizz")(5 "Buzz"))IF(=(MOD(1+ I)M)0)DO(PRINC S))(DO NIL((FRESH-LINE))(PRINC(1+ I)))))

... который, довольно напечатанный, является:

(lambda (n)
  (dotimes (i n)
    (loop for (m s) in '((3 "Fizz") (5 "Buzz"))
          if (= (mod (1+ i) m) 0)
          do (princ s))
    (do () ((fresh-line)) (princ (1+ i)))))

Тестирование полученной функции:

CL-USER> ((lambda (n)
  (dotimes (i n)
    (loop for (m s) in '((3 "Fizz") (5 "Buzz"))
          if (= (mod (1+ i) m) 0)
          do (princ s))
    (do () ((fresh-line)) (princ (1+ i))))) 20)
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz


1

Желе , 88 84 83 73 байта

Самый короткий ответ на данный момент (превосходит предыдущий «самый короткий ответ» на 1 байт)

Составитель:

Ṿ€“ḍ@€“ẋ"ЀF€ȯ"”jµFF?⁾RY

Попробуйте онлайн! (компилятор)

Попробуйте онлайн! (подтвердите счет bytecount)


Статистика:

19 24 компилятор
   20 гольф
17   2 фото
   27 fizzbuzz
83 73 всего

Приятно видеть, как меня избивают.
Вейцзюнь Чжоу

0

C, всего 1080 байт

Компилятор [369 байт]

#include<stdlib.h>
r,t,f=3,b=5,n;char*F="FIzz",*B="buZZ";main(int c,char **v){if(f)for(c=atoi(v[1]),n=1;c>=n;)r=f?n%f:0,r?(t=b?n%b:0)?printf("%i\n",n):puts(B):r?printf("%s%s\n",F,B):puts(F),++n;else for(c=0;c<atoi(v[1]);)printf("%i\n",++c);}

Fizz Buzz [241]

#include<stdlib.h>
r,t,f=3,b=5,n;char*F="FIzz",*B="buZZ";main(int c,char **v){if(f)for(c=atoi(v[1]),n=1;c>=n;)r=f?n%f:0,r?(t=b?n%b:0)?printf("%i\n",n):puts(B):r?printf("%s%s\n",F,B):puts(F),++n;else for(c=0;c<atoi(v[1]);)printf("%i\n",++c);}

Гольф [237]

#include<stdlib.h>
r,t,f=1,b=0,n;char*F="golf",*B="";main(int c,char **v){if(f)for(c=atoi(v[1]),n=1;c>=n;)r=f?n%f:0,r?(t=b?n%b:0)?printf("%i\n",n):puts(B):r?printf("%s%s\n",F,B):puts(F),++n;else for(c=0;c<atoi(v[1]);)printf("%i\n",++c);}

Количество [233 байта]

#include<stdlib.h>
r,t,f=0,b=1,n;char*F="",*B="";main(int c,char **v){if(f)for(c=atoi(v[1]),n=1;c>=n;)r=f?n%f:0,r?(t=b?n%b:0)?printf("%i\n",n):puts(B):r?printf("%s%s\n",F,B):puts(F),++n;else for(c=0;c<atoi(v[1]);)printf("%i\n",++c);}

0

постоянный ток , 434 байта

[:a]sa[91Pn93Pznlanps_znlanz0<R]sR[[[lj1-;aP1sb]sB0sj[dljd2+sj;a%0=Bljlz>F]sF[p2Q]sP]P]sI[[[]sF[pq]sP]nq]sN[z0=Nzn[sz]PlRxlIx]x[sn0dsb[1+0sjlFx[lb0=PAP]x0sbdln>M]dsMx]P

Попробуйте онлайн!

Входные данные для компилятора (168 байт) должны быть помещены в стек как целое число, строка, целое число, строка и т. Д. ( 3 [Fizz] 5 [Buzz]). Это должно быть дано в том порядке, в котором нужно печатать их шипение и жужжание, что может быть чем-то вроде мошенничества (если dcраньше я использовал пузырьковую сортировку , я думаю, это будет стоить мне около 100 байт), но это также позволяет пользователю Скажем, у «Fizz» еще 3, а «Buzz» - 5, но у «BuzzFizz» 15.

Я уверен, что это может быть игра в гольф немного больше; Основной макрос в конечной программе ( M) опирается на два макроса ( Fи P), которые довольно ненужны, если не вводить данные. Прямо сейчас компилятор проверяет на вход и выводит разные (гораздо меньшие) версии этих макросов, если их нет, но я не уверен, что вся установка оптимальна.

Сам компилятор довольно прост, он просто проверяет, есть ли в стеке «правила», и если это так, он печатает код, в котором хранится глубина стека z, сохраняет стек в массиве с 0 индексами a, а затем печатает обобщенный Код FizzBuzz. Если в стеке ничего не было, он просто печатает измененную версию кода FizzBuzz. Тестовые случаи:

Нет ввода (46 байт):

[]sF[pq]sPsn0dsb[1+0sjlFx[lb0=PAP]x0sbdln>M]dsMx

3 [Fizz] 5 [Buzz] (117 байт):

4sz[Buzz]3:a5
2:a[Fizz]1:a3
0:a[lj1-;aP1sb]sB0sj[dljd2+sj;a%0=Bljlz>F]sF[p2Q]sPsn0dsb[1+0sjlFx[lb0=PAP]x0sbdln>M]dsMx

1 [Golf] (103 байта):

2sz[Golf]1:a1
0:a[lj1-;aP1sb]sB0sj[dljd2+sj;a%0=Bljlz>F]sF[p2Q]sPsn0dsb[1+0sjlFx[lb0=PAP]x0sbdln>M]dsMx

Все они ожидают значение n в стеке, в котором оно хранится n. Те, у которых есть «правила», помещают их в массив aсо строками с нечетными индексами и целыми числами с четными. Основной макрос, Mувеличивает все, что находится в стеке, запускает макрос, Fкоторый проверяет значение по отношению к массиву a, проверяет, Fустановлено ли в регистре bзначение true или нет, и печатает верхнюю часть стека, если это так, или bперевод строки, если нет, сбрасывает в false и затем сохраняет работает сам, если nеще не был достигнут. Макрос F, учитывая правила, проходит через весь массив в поисках совпадений. Он увеличивается на два, поскольку наши целые числа и строки переплетаются через массив, а при совпадении вызывает макросB . макросBпросто получает строку (текущая позиция в массиве меньше единицы) и печатает ее. Это также устанавливает bправду. Наш компилятор не печатает Bбез ввода и, по сути, делает Fnop.


0

vim, 122 (компилятор) + 73 (пусто) + 90 (гольф) + 123 (fizzbuzz) = 392 байта

составитель

:%s/\v(.*):(.*)/qq\1jA\2<C-V><C-V><C-V><ESC>q=@qgg
VgggJAddGdd:%s/\v[0-9]*([^0-9])/\1
<C-V><ESC>:%@n
:w
:so! %
<ESC>ggii%s/=/<C-V><ESC><C-V><C-A>a/g<C-V><ESC>"ncc:%!seq 0 =
<ESC>

Формат ввода

3:Fizz
5:Buzz

Сгенерированный код для случая FizzBuzz

i%s/=/<ESC><C-A>a/g<ESC>"ncc:%!seq 0 =
qq3jAFizz<C-V><ESC>q=@qggqq5jABuzz<C-V><ESC>q=@qggddGdd:%s/\v[0-9]*([^0-9])/\1
<ESC>:%@n
:w
:so! %

Сгенерированный код, аннотированный

# replace the input number with a regex that replaces the placeholder (=) 
# with the real number + 1 (we'll need an extra line as a terminator later)
i%s/=/<ESC><C-A>a/g<ESC>

# pull the substitution command into register c and enter insert mode
"ncc

# create the numbers 0..N+1
:%!seq 0 =

# for each word, scan down k lines at a time and append the word to each
qq3jAFizz<C-V><ESC>q=@qgg
qq5jABuzz<C-V><ESC>q=@qgg

# delete the 0 and N+1 lines
ddGdd

# remove the numbers from any line with words
:%s/\v[0-9]*([^0-9])/\1
<ESC>

# Run the command we created at the beginning, replacing the placeholder 
# with the real number
:%@n

# The file now contains yet another program, with the constants defined.   
# Save and run.
:w
:so! %

# The file now contains a program that, when run on a buffer containing 
# a single line with a number, will produce the appropriate output

<C-V>0x16. <ESC>0x1b. <C-A>0x01.

Пример сеанса

$ cat code.txt
2:Foo
4:Bar
$ cat input.txt
8
$ { cat compile.vim; echo ':wq'; } | vim code.txt
# code.txt now contains the generated code
$ { cat code.txt; echo ':wq'; } | vim input.txt
$ cat input.txt
1
Foo
3
FooBar
5
Foo
7
FooBar

Когда я пытаюсь определить и запустить макрос из другого макроса, происходит нечто странное. Если мне удастся разобраться с этим, я мог бы сэкономить несколько байтов по сравнению с подходом сохранения и исходного кода.
Рэй

-2

SlooSarksi .Lang, 179

%%--43^jjk"/][][0[#!#111# h SD G ergDFGdfg[]9--99+==

10
Я не знаком с этим языком; не могли бы вы связать нас со страницей, описывающей это?
lirtosiast
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.