Bir FizzBuzz derleyicisi oluşturma


17

Derleyici golf dünyasına hoş geldiniz. Senin görevin spec üzerinde FizzBuzz bir varyant oynamak için başka bir program üreten bir program yazmaktır.

Derleyiciniz

Belirtilecek FizzBuzz programının varyantlarını üreten bir derleyici yazın. Bu varyantın spesifikasyonu bir tamsayı / dize çifti dizisi şeklinde ifade edilir.

  • Giriş, dilinize uygun herhangi bir biçimde olabilir. (Örneklerim n: xxxx kullanıyor, ancak bu yalnızca açıklama amaçlıdır.)
  • Her tamsayı girişi derleyicinizin her çağrısında yalnızca bir kez kullanılabilir.
  • Her çiftin tamsayısının değeri en az bir olacaktır.
  • Her çiftin dizesi tam olarak dört ASCII harfinden oluşacaktır.
  • Çıktı, aşağıdaki kurallara uyan tek bir tam program olmalıdır.
  • Metinsel bir program olduğu sürece çıktı herhangi bir uygun biçimde olabilir. (Yani geri dönen lambda ifadeleri yok.)

Yukarıdaki kurallara uymayan girdiler için davranış tanımlanmamıştır.

Oluşturduğunuz FizzBuzz programı

Derleyiciniz tarafından oluşturulan program girdi olarak tek bir tamsayı ( n) alacaktır . Gerektiğinde sayıları FizzBuzz dizeleriyle değiştirerek, n'den başlayarak n'ye kadar bir sayı dizisi çıkarır.

  • Oluşturulan program derleyici ile aynı dilde olmalıdır.
  • N girdisi dilinize uygun herhangi bir biçimde olabilir.
  • n değeri en az bir olacaktır.
  • Derleyiciye girilen tamsayıların en az birinin katları olan bir sayı, bir araya getirilen tamsayılarla eşlenen tüm dizelerle değiştirilmelidir.
  • FizzBuzz dizesi ile değiştirilmeyecek bir sayının ondalık ASCII biçiminde çıktısı alınmalıdır.

Örneğin;

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

puanlama

Girişiniz, derleyicinizin oluşturduğu programların uzunluğu ile derleyicinizin uzunluğuna eklenir. Derleyicinizi aşağıdaki parametrelerle birçok kez çalıştırın ve puanınızı bulmak için oluşturulan programların uzunluklarını derleyicinin uzunluğu ile birlikte ekleyin.

  1. Sadece Say. (Giriş yok - Oluşturulan program, değiştirilmeden 1 ila n arasında sayılır .)
  2. Sadece Golf. (1: Golf - Oluşturulan program n kez "Golf" üretir .)
  3. Klasik FizzBuzz. (3: Fizz, 5: Vızıltı)

(Derleyicinizin yalnızca listelenenler için değil, geçerli herhangi bir giriş için kod oluşturması gerektiğini unutmayın.)


derleyici uzunluğu için hiçbir puanlama ??
Sparr

tamsayıların tek haneli olduğunu varsayabilir miyiz? dizelerde boşluk olmadığını?
Sparr

@Sparr (İki basamaklı tamsayılar) fark yaratır mı? Unutmayın, sadece puanınızı oluşturan kod üretilir.
billpg

Eh, fizzbuzz internette başka bir yerde zaten son derece iyice golfçü bir sorundur. Denediysem çözümü okumayı unutabilir miyim bilmiyorum.
Sparr

1
Sonunda AWK'da yazmak mantıklı bir golf meydan okuma.
shadowtalker

Yanıtlar:


8

Python 3 - 168 162 + 230 = 392

Oh, Python, çok import sys;sys.argvuğraşıyorsun , ama 4 ile çarpmak gerçekten acıyor!

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)"))

Çıktı programları:

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))
  • Ana program için beklenen girdi, Python tuples'ın değerlendirilebilir bir sırasıdır veya girişsizdir '()'. (Sen "uygun" dedin.) Örnek girişi: '()', '("Golf",1),', '("Fizz",3),("Buzz",5)'Not kabuk için alıntı ve bir giriş için virgül sondaki.

  • Diksiyondan (tanımsız sipariş!) Tuple'a geçerek 01:00 hatası düzeltildi.

  • Diğer programlar için beklenen girdi sadece sayıdır


Örnek komut satırı argümanınızda, çift tırnak içine almak ve 'Fizz' ve 'Buzz' için tek tırnak kullanmak zorunda kaldım - öyle ki "" {3: 'Fizz', 5: 'Buzz'} "ancak program hala benim için bir hata atıyor.
James Williams

Hata nedir?
Jason S

@JasonS - Merhaba. Bu meydan okuma deneyiminizle ilgileniyorum. meta.codegolf.stackexchange.com/questions/5050/…
billpg

6

perl6 376 340 84 + 115 = 199

GÜNCELLEME: sayolmadan almak için perl5'ten perl6'ya geçti use feature.

GÜNCELLEME: beş yerine üç test örneği

FizzBuzz'a halihazırda golf oynayan yüzlerce çözüm var ve birçok yarışma aynı sonuçla bitiyor, bu yüzden başladım. Derleyicim bu çözümün özelleştirilmiş bir sürümünü üretiyor. "Sadece say" varyasyonunu hesaba katmak için birkaç karakter daha eklendi.

derleyici, şöyle argümanlar bekler: "Fizz 3" "Buzz 5"

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

derlenmiş programlar, böyle bir argüman bekliyoruz: 100

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

eski test senaryoları için derlenmiş programlar:

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

Soruların yorumlarında tartışıldığı gibi kuralları değiştirdim. Puanınızı yeniden hesaplamak isteyeceksiniz.
billpg

@billpg yapıldı ve geliştirildi :)
Sparr

Merhaba. Bu meydan okuma deneyiminizle ilgileniyorum. meta.codegolf.stackexchange.com/questions/5050/…
billpg

3

Pyth - 51 + (38 + 43 + 50) = 182 bayt

Muhtemelen derleyici birkaç bayt golf olabilir. Hepsinin bağlantıları çevrimiçi tercümanın kalıcı bağlantılarıdır.

Derleyici - 51 bayt

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

Sadece bir giriş demetiyle dize biçimlendirmesi yapar. Gibi girdi alır:

3 5
Fizz Buzz

Hiçbir şey - 38 bayt

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

Just Golf - 43 bayt

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

Klasik Fizz Buzz - 50 bayt

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

2

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

Buraya ilk katılım, bu zorluk en zor olanlar arasında değil, bu yüzden denemeyi düşündüm. Yine de C ++ kullanarak ve hatta C ++ 11 eklemeleri ile hala oldukça ayrıntılı bir dildir, ancak eminim iyileştirme için yer var.

Derleyici (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 5BuzzVb. Şeklinde argümanları varsayar .

Sayı (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";}}

Golf (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";}}

Ek bilgi

GCC 4.8.1 ile test edilmiştir, derleyici hileleri yoktur.

İşte test senaryolarının oluşturulmasını otomatikleştirmek ve çalıştırmak için küçük bir makefile (kullanım 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

Merhaba. Bu meydan okuma deneyiminizle ilgileniyorum. meta.codegolf.stackexchange.com/questions/5050/…
billpg

map<int,string> folabilir map<int,string>f. İle j=1aynı anda başlatabilirsiniz z.
Yytsi

2

Yakut 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}"

Kullanımı:

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

Çalıştır ve hata ayıkla

Şimdiye kadar en kısa cevap Jelly tarafından şaşırtıcı bir şekilde dövülmedi. Stax'ta sağlanan dize şablonu gerçekten düzgün ve printf benzeri işlevler sağlar. Derleyici tarafından oluşturulan programlar neredeyse her zaman en iyisi elle kodlama ile paketleme kullanmadan elde edebilecek kadar kısadır.

Derleyicinin kendisi 23 bayttır uzunluğundadır.

ASCII eşdeğeri:

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

Girilen girdi [], bunu oluşturur (5 bayt)

mzc_?

Çalıştır ve hata ayıkla

Girilen girdi [[1,"Golf"]], bunu üretir (17 bayt)

mz_1%z"Golf"?+c_?

Çalıştır ve hata ayıkla

Girilen girdi [[3,"Fizz"],[5,"Buzz"]], bunu oluşturur (29 bayt)

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

Çalıştır ve hata ayıkla


1

Ortak 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)))

Çektiğim benim diğer cevabı ve giriş parametrelerini eklerken quasiquotes sardı. Elde edilen formu tek satır olarak yazdırıyorum ve gereksiz boşluk karakterlerini kaldırıyorum. Derleyici önceki sürümden biraz daha uzun, ancak elde edilen puan azaldı.

Puan

(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))))

Döndürülen değerler:

574
(215 111 119 129)

Güzel

(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)))

Giriş formatı (number string)çiftlerin bir listesidir . Örneğin:

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

... standart çıktıya yazdırır:

(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)))))

... güzel basılan:

(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)))))

Ortaya çıkan işlevi test etme:

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, toplam 1080 bayt

Derleyici [369 bayt]

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

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

Sayı [233 bayt]

#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 bayt

[: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

Çevrimiçi deneyin!

Derleyici için giriş (168 bayt) yığının üzerine tamsayı, dize, tamsayı, dize vb. ( 3 [Fizz] 5 [Buzz]) Olarak yerleştirilmelidir. Biraz hile olabilen (daha dcönce kabarcık sıralaması uyguladıktan sonra, bana yaklaşık 100 bayt mal olacağını düşünüyoruz) ama aynı zamanda kullanıcının , diyelim ki hala 'Fizz' 3'te ve 'Buzz' 5'te çalışıyor, ancak 15 verim 'BuzzFizz' var.

Eminim bu biraz daha golf olabilir; son programdaki ana makro ( M) iki makroya ( FveP hiçbir giriş verilen oldukça gereksizdir). Şu anda derleyici girdi olup olmadığını kontrol eder ve yoksa bu makroların farklı (çok daha küçük) sürümlerini çıkarır, ancak tüm kurulumun en uygun olduğundan emin değilim.

Derleyicinin kendisi oldukça basittir, sadece yığın üzerinde 'kurallar' olup olmadığını kontrol eder ve eğer öyleyse yığın derinliğini depolayan kodu yazdırır z, yığını 0 dizinli bir dizide saklar ave genelleştirilmiş yazdırır FizzBuzz kodu. Yığında hiçbir şey yoksa, gerçekten sadece FizzBuzz kodunun değiştirilmiş bir sürümünü yazdırır. Test senaryoları:

Giriş yok (46 bayt):

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

3 [Fizz] 5 [Buzz] (117 bayt):

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 bayt):

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

Hepsi yığındaki n değerini bekler , bu depolanır n. 'Kurallara' sahip olanlar, diziyi atek dizinlerde ve tamsayılar eşit olacak şekilde diziye yerleştirir . Ana makro, Myığındaki her şeyi artırır F, değeri diziye karşı kontrol eden a, Fset kaydının bdoğru olup olmadığını kontrol eder ve varsa yığının üstünü veya yoksa yeni satırı byazdırır, falsiye sıfırlanır ve ardından tutar nhenüz ulaşılmadıysa kendini çalıştırıyor . FKurallar verilen makro , eşleşmeleri arayan dizinin tamamından geçer. Tamsayılarımız ve dizelerimiz dizi aracılığıyla dokunduğundan ve bir maçta makro çağırdığı için iki kat artar.B . MakroBsadece dizeyi alır (dizideki geçerli konum daha az bir) ve yazdırır. Aynı zamanda bgerçeği belirler . Derleyicimiz bir nop yazdırmaya zahmet etmiyor .B hiçbir girdi veF


0

vim, 122 (derleyici) + 73 (boş) + 90 (golf) + 123 (fizzbuzz) = 392 bayt

Derleyici

:%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>

Giriş biçimi

3:Fizz
5:Buzz

FizzBuzz durumu için oluşturulan kod

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! %

Oluşturulan Kod, Ek Açıklama

# 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'dir.<C-A>0x01'dir.

Örnek oturum

$ 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

Başka bir makrodan bir makro tanımlayıp çalıştırmaya çalıştığımda garip bir şeyler oluyor. Bunu çözmeyi başarırsam, kaydet ve kaynakla yaklaşımından birkaç bayt tasarruf edebilirim.
Ray

-2

SlooSarksi Uzun, 179

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

10
Bu dile aşina değilim; Bizi açıklayan bir sayfaya bağlar mısınız?
lirtosiast
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.