富里耶的高尔夫球场


24

挑战

给定一个字符串作为输入,沿输出该字符串的Fourier程序运行

在Fourier中,没有简单的方法来输出字符串:您必须检查每个字符代码并将其输出为字符。

傅里叶

该语言基于累加器,该累加器是全局变量,在程序启动时将其初始化为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

更多信息

您只能使用上述运算符。因此,如果输出的傅里叶程序使用以下任何一项,则它是无效的(请注意,允许使用以下运算符作为赏金):

  • 重复循环
  • 如果陈述
  • 变数
  • 随机
  • 模数
  • 用户输入
  • 大于/小于运算符
  • 平等经营者
  • 清除萤幕
  • 时间延迟
  • 日期功能

您的程序可以是完整程序,也可以是函数,可以通过STDIN,文件或函数参数输入。您也可以直接从Internet获取输入。

请注意,如果vv您的代码中包含,则应将其替换为-2。这同样适用于^^与替换它+2

例子

如果输入为7n,则预期程序为:

55a110a

但是你可以用

55a*2a

另一种方法是

7o110a

使用号码了。


同样,如果输入为Hello,则预期程序为:

72a101a108a108a111a

您可以将其压缩3个字节(因为输出不会更改累加器):

72a101a108aa111a

但是,等等,我们可以使用加法运算符,节省2个字节:

72a101a+7aa+3a

格式化

因为我将使用MartinBüttner的Stack Snippet排行榜,所以请您格式化标题,如下所示:

# <Language name>, <length of total output> bytes

然后,您可以将任何想要的内容放在标题下方。

获奖

您应该发布傅立叶程序的长度(由代码生成)以输出此文本文件此文本文件。您的分数是两个Fourier程序的总长度(以字节为单位)(Fourier中未使用非ASCII字符,因此这实际上没有任何区别)。

得分最低的人获胜。如果有平局,则以字节为单位的最短程序获胜。

赏金

这500 rep赏金是针对一个新的答案的,它可以使用Fourier的任何功能来打高尔夫球。其中包括变量,循环和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&]*(?:&lt;(?:s&gt;[^&]*&lt;\/s&gt;|[^&]+&gt;)[^\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>


6
我认为不必输出所有最佳解决方案是非常公平/有趣的。它排除了除蛮力之外的所有实现方式…
orlp

5
必须输出所有最优解的真正问题是,对于长输入,将存在更多的最优解,而宇宙中将存在原子。
isaacg 2015年

1
@orlp编辑输出所有最佳解决方案
Beta Decay

1
它应该仅是可打印的ASCII还是任何类型的ASCII?而且只有7位ASCII还是全字节?
orlp

1
累加器是否从0开始?
ASCIIThenANSI

Answers:


9

Python,14307118字节

哈姆雷特(Hamlet)的601216 +创世纪(Genesis)的13705902 = 14307118

肯定有一些senarios下此解决方案不是最优的,比如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))

@Shebang好吧,我敢肯定Geobit的结果是错误的,请参阅我的评论。
isaacg 2015年

它几乎没有,但您仅赢了5个字符(您和Razvan并列,所以我用您的代码长度作为决胜局)
Beta Decay

2
@BetaDecay我之前从未见过长度决胜局在两个非高尔夫程序之间是相关的。
isaacg's

是的...我都不是:P
Beta Decay

13

> <>,​​14310665字节

小村庄的601398 +创世的13709267

这项工作仍在进行中,需要大量时间才能完成。

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'<

那太疯狂了,可惜这并不是最佳选择。
orlp

我正在使用/,*和o,但是它开始占据更多位置。
亚伦

18
没关系,每次讲故事,鱼通常都会长大;)
Geobits 2015年

好吧,这是一种绝佳的语言选择:D
Beta Decay

您的程序不符合赏金标准(没有发布答案),因此我将其授予了您,因为我喜欢您使用<> <。
Beta Decay

8

Java,14307140字节

哈姆雷特-601,218

创世记-13,705,922

这里的想法是通过创建一个角色->角色图来预先完成所有工作。然后,您可以循环浏览并获取最短的字符串。

数字必须有一点例外,因此我在主循环中检查它们。不过,它仍然很快,并且可以在几秒钟内处理更大的测试用例。我也许可以对本节进行一些调整,但我相当确定它已经接近最佳状态。

输入是一个文件名作为参数。将输出写入文件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();
    }

}

我认为这不能正确处理以零开头的数字字符串。例如,在input上01,我相信它会输出01o,这是不正确的。
isaacg

另外,我认为您正在滥用蓄电池。在else主循环的子句中,您可以在使用累加器的实际值和前一个字符的字符值之间进行选择。如果两者不同,则无法选择后者,因为这意味着您使用o了之前的时间,并且累加器不包含前一个字符的值。
isaacg 2015年

对,现在都应该修复。谢谢!
Geobits,2015年

当我在机器上运行此程序时,对于Hamlet而言,我得到625474,对于Genesis,而言,我得到13705922。
isaacg 2015年

@isaacg您是否在同一文件(具有相同的行尾)上运行它?我之前遇到行尾的问题。当我和您的我在同一个文件上运行时,它们都显示发布的分数。
Geobits,2015年

2

PHP,14307118字节

601,216(哈姆雷特)+ 13,705,902(圣经)

function f($file) {
    $text = file_get_contents($file);

    $a = 0;

    for ($i = 0; $i < strlen($text); $i++) {
        $chr = $text[$i];

        if (ctype_digit($chr)) {
            while ($chr && isset($text[$i + 1]) && ctype_digit($text[$i + 1])) {
                $chr .= $text[$i + 1];
                $i++;
            }

            if ($a == (int)$chr) {
                print "o";
            }
            else {
                $a = (int)$chr;
                print $chr . "o";
            }

            continue;
        }

        $ord = ord($chr);

        $mapping = array(
            '' => $a,
            '^' => $a + 1,
            'v' => $a - 1
        );

        for ($j = 2; $j <= 9; $j++) {
            $mapping["+$j"] = $a + $j;
            $mapping["-$j"] = $a - $j;
            $mapping["*$j"] = $a * $j;
            $mapping["/$j"] = $a / $j;
        }

        foreach ($mapping as $op => $value) {
            if ($value === $ord) {
                $a = $value;
                print $op . "a";
                continue 2;
            }
            else if ($value . '' === $chr) {
                $a = $value;
                print $op . "o";
                continue 2;
            }
        }

        $a = $ord;
        print $ord . "a";
    }
}

哈姆雷特的傅立叶输出

其工作方式如下:

  1. 遍历输入中的每个字符;
  2. 如果序列中有一个非零的前导数字,它将把累加器设置为该数字并将其输出为数字。它还检查相似的数字;
  3. 否则,检查是否有更短的方法来输出当前字符(而不是ASCII代码+“ a”符号= 4个字符),方法是对累加器执行基本操作(+-* /),其数字在2到9之间;显然,它也尝试比较/增加/减少;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.