Створіть компілятор 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: Гольф - створена програма виводить "Гольф" n разів.)
  3. Класичний FizzBuzz. (3: Fizz, 5: Buzz)

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


немає балів за довжину компілятора ??
Спарр

чи можна вважати цілі числа однозначними? що в рядках немає пробілів?
Спарр

@Sparr Чи це (двоцифрові цілі числа) змінило б значення? Пам'ятайте, його єдиний згенерований код, який робить ваш рахунок.
billpg

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

1
Нарешті виклик у гольф, який насправді має сенс писати в AWK.
shadowtalker

Відповіді:


8

Пітон 3 - 168 162 + 230 = 392

О, Python, ти так стараєшся, але множення цього 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 ранку шляхом переходу від dict (невизначеного замовлення!) На кортежі.

  • Очікуваний вхід для інших програм - це просто число


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

Що таке помилка?
Jason S

@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 зроблено та вдосконалено :)
Sparr

Привіт там. Мене цікавить ваш досвід цього виклику. 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

C ++ 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, жоден чит компілятор.

Ось невеликий makefile для автоматизації генерації тестових випадків та їх запуску (використання 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

Стакса , 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

Спробуйте в Інтернеті! (компілятор)

Спробуйте в Інтернеті! (підтвердьте рахунок рахунку)


Статистика:

19 24 укладач
   20 гольфу
17   2 підрахунок
   27 фізбуз
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 [Гольф] (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на truthy чи ні, і друкує верхню частину стека, якщо так, або новий рядок, якщо ні, скидає bв false, а потім зберігає працює сам, якщо nще не досягнуто. МакросF , задавши правила, проходить весь масив, шукаючи відповідність. Він збільшується на два, оскільки наші цілі числа та рядки переплетені через масив, а на відповідність він називає макросB . МакросBпросто витягує рядок (поточне положення в масиві менше одиниці) та друкує її. Він також налаштований bна truthy. Наш компілятор не намагається надрукувати nop.B без введення, і по суті робитьF


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.