FizzBuzz 컴파일러 생성


17

컴파일러 골프의 세계에 오신 것을 환영합니다. 귀하의 작업은 사양에 따라 FizzBuzz의 변형을 재생하기 위해 다른 프로그램을 생성하는 프로그램을 작성하는 것입니다.

컴파일러

사양에 따라 FizzBuzz 프로그램의 변형을 생성하는 컴파일러를 작성하십시오. 이 변형의 스펙은 정수 / 문자열 쌍의 배열 형식으로 표현됩니다.

  • 입력은 귀하의 언어에 편리한 형태 일 수 있습니다. (내 예제는 n : xxxx를 사용하지만 이는 단지 설명을위한 것입니다.)
  • 각 정수 입력은 컴파일러 호출 당 한 번만 사용할 수 있습니다.
  • 각 쌍의 정수는 적어도 하나의 값을 갖습니다.
  • 각 쌍의 문자열은 정확히 4 개의 ASCII 문자로만 구성됩니다.
  • 출력은 아래 규칙을 따르는 하나의 완전한 프로그램이어야합니다.
  • 텍스트 프로그램 인 경우 출력은 편리한 형태 일 수 있습니다. (따라서 람다 식을 반환하지 않습니다.)

위 규칙을 준수하지 않는 입력에 대해서는 동작이 정의되어 있지 않습니다.

생성 된 FizzBuzz 프로그램

컴파일러가 생성 한 프로그램은 단일 정수 n 을 입력으로 사용합니다. 필요한 경우 숫자를 FizzBuzz 문자열로 대체 하여 1부터 n 까지의 일련의 숫자를 출력 합니다.

  • 생성 된 프로그램은 컴파일러와 동일한 언어 여야합니다.
  • 입력 n 은 귀하의 언어에 편리한 형태 일 수 있습니다.
  • n 은 하나 이상의 값을 갖습니다.
  • 컴파일러에 입력 된 정수 중 적어도 하나의 배수 인 숫자는 함께 연결된 정수와 쌍을 이루는 모든 문자열로 바꿔야합니다.
  • FizzBuzz 문자열로 대체되지 않는 숫자는 10 진수 ASCII로 출력되어야합니다.

예를 들어;

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

채점

입력 한 내용은 컴파일러가 생성 한 프로그램의 길이에 따라 컴파일러의 길이에 추가됩니다. 다음 각 매개 변수를 사용하여 컴파일러를 여러 번 실행하고 생성 된 프로그램의 길이와 컴파일러의 길이를 더하여 점수를 찾으십시오.

  1. 그냥 센다. (입력 없음-생성 된 프로그램은 교체없이 1에서 n 까지 카운트 합니다.)
  2. 그냥 골프. (1 : 골프-생성 된 프로그램은 "골프"를 n 번 출력 합니다.
  3. 클래식 FizzBuzz. (3 : 피즈, 5 : 버즈)

(컴파일러는 나열된 것뿐만 아니라 유효한 입력을위한 코드를 생성해야합니다.)


컴파일러의 길이에 대한 점수가 없습니다 ??
Sparr

정수가 한 자릿수라고 가정 할 수 있습니까? 문자열에 공백이 없다고?
Sparr

@Sparr (2 자리 정수) 차이가 있습니까? 점수를 생성하는 유일한 코드 만 기억하십시오.
billpg

음, fizzbuzz는 인터넷의 다른 곳에서 이미 매우 철저한 골프 문제입니다. 시도하면 솔루션을 읽는 것을 잊어 버릴 수 있는지 모르겠습니다.
Sparr

1
마지막으로 AWK로 작성하는 것이 의미가있는 골프 도전입니다.
shadowtalker

답변:


8

파이썬 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))
  • 메인 프로그램에 대한 예상 입력은 평가 가능한 파이썬 튜플 시퀀스이거나 '()'입력이 없습니다. (당신은 "편리"라고했다.) 예 입력 : '()', '("Golf",1),', '("Fizz",3),("Buzz",5)'참고 쉘 인용 한 입력에 쉼표를 후행.

  • dict (정의되지 않은 순서!)에서 튜플로 변경하여 오전 1시 실수를 수정했습니다.

  • 다른 프로그램에 대한 예상 입력은 숫자입니다


예제 명령 줄 인수에서 큰 따옴표로 묶고 'Fizz'와 'Buzz'에 작은 따옴표를 사용해야했습니다.` "{3 : 'Fizz', 5 : 'Buzz'}"그러나 프로그램은 여전히 나를 위해 오류를 던지고.
James Williams

오류가 무엇입니까?
Jason S

@JasonS-안녕하세요. 이 도전에 대한 귀하의 경험에 관심이 있습니다. meta.codegolf.stackexchange.com/questions/5050/…
billpg

6

perl6 376 340 84 + 115 = 199

업데이트 : perl5에서 perl6으로 전환하여 saywithout use feature.

업데이트 : 5 개 대신 3 개의 테스트 사례

FizzBuzz에는 이미 수백 가지의 골프 솔루션이 있으며 많은 대회가 같은 결과로 끝나므로 여기서 시작했습니다. 내 컴파일러는 해당 솔루션의 사용자 정의 버전을 생성합니다. "그냥 카운트"변형을 설명하기 위해 몇 개의 추가 문자가 삽입되었습니다.

컴파일러는 "Fizz 3" "Buzz 5"와 같은 인수를 기대합니다.

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

컴파일 된 프로그램은 다음과 같은 인수를 기대합니다.

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

클래식 피즈 버즈 -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";}}

피즈 버즈 (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입니다 (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

스탁스 , 23 + 5 + 17 + 29 = 74

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

실행 및 디버깅

지금까지 가장 짧은 답변 Jelly가 당연히 구타 한 것은 아닙니다. Stax에서 제공하는 문자열 템플릿은 정말 깔끔하며 printf와 비슷한 기능을 제공합니다. 컴파일러에 의해 생성 된 프로그램은 패킹을 사용하지 않고 수동으로 코드 골프를 수행함으로써 얻을 수있는 가장 짧은 프로그램입니다.

컴파일러 자체의 길이 는 23 바이트 입니다.

ASCII는 다음과 같습니다.

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

제공된 input [], 이것을 생성합니다 (5 바이트)

mzc_?

실행 및 디버깅

제공된 input [[1,"Golf"]], 이것을 생성합니다 (17 바이트)

mz_1%z"Golf"?+c_?

실행 및 디버깅

제공된 input [[3,"Fizz"],[5,"Buzz"]], 이것을 생성합니다 (29 바이트)

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

실행 및 디버깅


1

일반적인 Lisp, 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)))

나는 갔다 내 다른 대답을 입력 매개 변수를 추가하는 동안 quasiquotes에 싸서. 결과 양식을 한 줄로 인쇄하고 불필요한 공백 문자를 제거합니다. 컴파일러는 이전 버전보다 약간 길지만 결과 점수는 줄어 듭니다.

점수

(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



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);}

피즈 버즈 [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

dc , 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]). 그것은 속임수의 비트 수 있습니다 하나는 자신의 fizzes와 버즈가 인쇄하고자하는 순서에 주어져야한다 (일종의 거품을 구현하는 데 dc전에, 나는 그것이 나에게 약 100 바이트 비용이 생각)하지만 그것도 할 수있게합니다 예를 들어 여전히 3에서 'Fizz'를 실행하고 5에서 'Buzz'를 실행하지만 15의 수율 'BuzzFizz'를 갖습니다.

나는 이것이 조금 더 골프를 칠 수 있다고 확신한다. 최종 프로그램의 주요 매크로 (M ) 두 개의 매크로 ( FP 입력이없는 경우 다소 불필요한 ) 합니다. 현재 컴파일러는 입력을 확인하고 이러한 매크로의 다른 (훨씬 작은) 버전이없는 경우 전체 설정이 최적인지 확실하지 않습니다.

컴파일러 자체는 매우 간단하며 스택에 '규칙'이 있는지 확인하고 스택 깊이를 저장하는 코드를 인쇄 z하고 스택을 0 인덱스 배열에 저장합니다.a 한 다음 일반화를 인쇄합니다. FizzBuzz 코드 스택에 아무것도 없으면 실제로 수정 된 버전의 FizzBuzz 코드를 인쇄합니다. 테스트 사례 :

입력 없음 (46 바이트) :

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

3 [Fizz] 5 [버즈] (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를 진실로 설정 했는지 여부를 확인 하고 스택의 상단 또는 그렇지 않으면 개행을 인쇄하고 b거짓으로 재설정 한 다음 유지합니다. 문자열을 검색하고 (배열의 현재 위치가 1보다 작은 경우) 자체를 실행 하여 인쇄합니다. 또한 진실로 설정 됩니다. 우리 컴파일러는 입력없이 인쇄 를 귀찮게하지 않으며 본질적으로 nop를 만듭니다 .n 아직 도달하지 않은매크로F주어진 규칙에 따라 는 전체 배열을 통해 일치하는 항목을 찾습니다. 정수와 문자열이 배열을 통해 짜여지고 일치하는 경우 macro 호출하기 때문에 2 씩 증가합니다 B. 매크로BbBF


0

vim, 122 (컴파일러) + 73 (빈) + 90 (골프) + 123 (피즈 버즈) = 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

다른 매크로 내에서 매크로를 정의하고 실행하려고 할 때 이상한 일이 발생합니다. 이를 정리하면 저장 및 소스 접근 방식보다 몇 바이트를 절약 할 수 있습니다.
Ray

-2

SlooSarksi .Lang, 179

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

10
나는이 언어에 익숙하지 않다. 그것을 설명하는 페이지로 연결해 주시겠습니까?
lirtosiast
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.