给定一个字符串作为输入,在输出该字符串的傅里叶程序中向下打高尔夫。
在傅里叶中,没有一种简单的输出字符串的方法:您必须遍历每个字符代码并将其作为一个字符输出。
该语言以累加器为基础,累加器是一个全局变量,在程序开始时初始化为0。语言中几乎所有的操作符都使用这种方法。只有一些不改变累加器的值。
a
将累加器的值作为ASCII代码并输出字符。不会更改累加器的值。
如果累加器大于255,程序将返回一个错误。同样,如果累加器小于0。
o
输出累加器的值。不会更改累加器的值。
^
增加一个累加器。
v
将累加器减少一个。
+x
将累加器设置为累加器的值加上x的值。
-x
将累加器设置为累加器的值减去x的值。
*x
将累加器设置为累加器的值乘以x的值。
/x
将累加器设置为累加器的值除以x的值。(请注意,这是整数除法,因此1/6
生成0
)
n
将累加器设置为整数n。
在这里,x
和n
可以是从0
到2^32-1
包含的任意整数。
您必须只使用上面描述的运算符。因此,如果输出的Fourier程序使用以下任何一种方法(请注意,赏金允许使用下列运算符),则该程序无效:
您的程序可以是完整的程序,也可以是函数,通过STDIN、文件或函数参数输入。你也可以直接从互联网上获取信息。
注意,如果代码中有vv
,则应该用-2
替换它。^^
也是如此,用+2
代替它。
如果输入是7n
,那么预期的程序是:
55a110a
但是你可以用
55a*2a
另一种方式是
7o110a
用数字出来。
类似地,如果输入是Hello
,那么预期的程序是:
72a101a108a108a111a
您可以将它降低3个字节(因为输出不会改变累加器):
72a101a108aa111a
但是等等,我们可以使用加法运算符,保存两个字节:
72a101a+7aa+3a
由于我将使用Martin Büttner的Stack代码段领导板,请您将标题格式化如下:
# <Language name>, <length of total output> bytes
然后,你可以把你想要的任何东西放在标题下面。
您应该发布傅立叶程序的长度(由您的代码生成)以输出此文本文件和此文本文件。分数是以字节为单位的两个Fourier程序的合并长度(非ASCII字符没有在Fourier中使用,因此它并没有产生真正的影响)。
得分最低的人获胜。如果存在平数,则以字节为单位的最短程序将获胜。
这500代表赏金是一个新的答案,高尔夫球的字符串使用任何傅里叶函数。这包括变量、循环和if语句等。这个新的答案将不会被接受。
请参阅上面的格式化部分:
var QUESTION_ID=55384;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),e.has_more?getAnswers():process()}})}function shouldHaveHeading(e){var a=!1,r=e.body_markdown.split("\n");try{a|=/^#/.test(e.body_markdown),a|=["-","="].indexOf(r[1][0])>-1,a&=LANGUAGE_REG.test(e.body_markdown)}catch(n){}return a}function shouldHaveScore(e){var a=!1;try{a|=SIZE_REG.test(e.body_markdown.split("\n")[0])}catch(r){}return a}function getAuthorName(e){return e.owner.display_name}function process(){answers=answers.filter(shouldHaveScore).filter(shouldHaveHeading),answers.sort(function(e,a){var r=+(e.body_markdown.split("\n")[0].match(SIZE_REG)||[1/0])[0],n=+(a.body_markdown.split("\n")[0].match(SIZE_REG)||[1/0])[0];return r-n});var e={},a=1,r=null,n=1;answers.forEach(function(s){var t=s.body_markdown.split("\n")[0],o=jQuery("#answer-template").html(),l=(t.match(NUMBER_REG)[0],(t.match(SIZE_REG)||[0])[0]),c=t.match(LANGUAGE_REG)[1],i=getAuthorName(s);l!=r&&(n=a),r=l,++a,o=o.replace("{{PLACE}}",n+".").replace("{{NAME}}",i).replace("{{LANGUAGE}}",c).replace("{{SIZE}}",l).replace("{{LINK}}",s.share_link),o=jQuery(o),jQuery("#answers").append(o),e[c]=e[c]||{lang:c,user:i,size:l,link:s.share_link}});var s=[];for(var t in e)e.hasOwnProperty(t)&&s.push(e[t]);s.sort(function(e,a){return e.lang>a.lang?1:e.lang<a.lang?-1:0});for(var o=0;o<s.length;++o){var l=jQuery("#language-template").html(),t=s[o];l=l.replace("{{LANGUAGE}}",t.lang).replace("{{NAME}}",t.user).replace("{{SIZE}}",t.size).replace("{{LINK}}",t.link),l=jQuery(l),jQuery("#languages").append(l)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",answers=[],page=1;getAnswers();var SIZE_REG=/\d+(?=[^\d&]*(?:<(?:s>[^&]*<\/s>|[^&]+>)[^\d&]*)*$)/,NUMBER_REG=/\d+/,LANGUAGE_REG=/^#*\s*([^,]+)/;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table></div> <tbody id="languages"> </tbody> </table></div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody></table>
发布于 2015-08-27 16:28:40
在某些特定情况下,这个解决方案肯定不是最优的,例如对于1111
,它将输出1111o
而不是11oo
。然而,我认为这几乎是最优的。
编辑:通过将0o0o
改进为0oo
来保存几个字节。
包含输入的文件的名称在STDIN上接收,输出到STDOUT。
结果经官方翻译证实。
def opt_str(char, acc):
opts = []
char_num = ord(char)
opts.append(str(char_num))
if 0 < char_num - acc < 10:
opts.append('+' + str(char_num - acc))
if 0 < acc - char_num < 10:
opts.append('-' + str(acc - char_num))
if char_num - acc == 1:
opts.append('^')
if acc - char_num == 1:
opts.append('v')
if acc == char_num:
opts.append('')
if acc and char_num % acc == 0:
opts.append('*' + str(char_num//acc))
try:
if acc // (acc // char_num) == char_num:
opts.append('/' + str(acc // char_num))
except:
pass
return [opt for opt in opts if len(opt) == len(min(opts, key=len))]
acc = 0
result = []
pos = 0
with open(input(), "r") as myfile:
in_str = myfile.read()
while pos < len(in_str):
i = in_str[pos]
pos += 1
if i in '0123456789':
if i != '0':
while pos < len(in_str) and in_str[pos] in '0123456789':
i += in_str[pos]
pos += 1
if i == str(acc):
result.append('o')
else:
result.append(i + 'o')
acc = int(i)
else:
opts = opt_str(i, acc)
result.append(opts[0] + 'a')
acc = ord(i)
print(''.join(result))
发布于 2015-08-27 19:33:40
这仍是一项正在进行的工作,需要大量时间才能完成。
v
0
>i:0(?;:r-:?!v:0a-)?v v
>~:v ~ >:a(?v>
:1+?v~'v'o v o'^'~\:0)?v
>n vno'+' ^?=1:<
^ o'a'<
发布于 2015-08-27 17:31:25
这里的想法是预先做好所有的工作,制作一个字符->字符图。然后,你就可以循环通过和抓取最短的字符串。
对于数字,需要做一些例外处理,所以我在主循环中检查它们。不过,它仍然很快,并在几秒钟内处理更大的测试用例。我可能可以再调整几个字节,但我确信它接近最佳状态。
输入是作为参数的文件名。输出被写入文件inputFilename_out.4
,字符计数被发送到STDOUT。
这是1737个字节的平局,完全没有高尔夫球。如果需要的话,我可以打很多高尔夫球,但它还是会有点大。
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Paths;
import java.text.NumberFormat;
public class FourierMapper {
public static void main(String[] args) throws Exception {
FourierMapper fm = new FourierMapper();
fm.createMap();
String filename = args.length>0? args[0]:"bible.txt";
String out = fm.fourierize(filename);
System.out.println(out.length());
Files.write(Paths.get(filename + "_out.4"), out.getBytes(), new OpenOption[]{});
}
String[][] map = new String[9999][256];
void createMap(){
for(int from=0;from<9999;from++){
for(int to=0;to<256;to++){
if(to<10||from<1){
map[from][to] = ""+to;
} else if(to==from){
map[from][to] = "";
} else if(to-from==1){
map[from][to] = "^";
} else if(to-from==-1){
map[from][to] = "v";
} else if(to>99){
if(to%from<1){
map[from][to] = "*"+(to/from);
} else if(to>from&&to-from<10){
map[from][to] = "+"+(to-from);
} else if(from>to&&from-to<10){
map[from][to] = "-"+(from-to);
} else {
map[from][to] = ""+to;
}
} else {
map[from][to] = ""+to;
}
}
}
}
String fourierize(String filename) throws Exception{
StringBuilder out = new StringBuilder();
byte[] in = Files.readAllBytes(Paths.get(filename));
String whole = new String(in);
out.append(in[0] + "a");
int number = -1;
for(int i=1;i<in.length;){
if(in[i]<58&&in[i]>47){
number = in[i]==48?0:((Number)NumberFormat.getInstance().parse(whole.substring(i,i+4))).intValue();
out.append(""+number+"o");
i += (""+number).length();
} else {
if(number<0)
out.append(map[in[i-1]][in[i]]+"a");
else
out.append(map[number][in[i]]+"a");
number = -1;
i++;
}
}
return out.toString();
}
}
https://codegolf.stackexchange.com/questions/55384
复制相似问题