Dây golf trong Fourier


24

Thử thách

Đưa ra một chuỗi làm đầu vào, đánh xuống chương trình Fourier để tạo ra chuỗi đó.

Trong Fourier, không có cách dễ dàng nào để xuất một chuỗi: bạn phải đi qua từng mã ký tự và xuất ra dưới dạng một ký tự.

Fourier

Ngôn ngữ dựa trên bộ tích lũy, một biến toàn cục được khởi tạo thành 0 khi bắt đầu chương trình. Điều này được sử dụng bởi hầu hết mọi nhà khai thác trong ngôn ngữ. Chỉ một số không thay đổi giá trị của bộ tích lũy.

Nhân vật ra

a

Lấy giá trị của bộ tích lũy làm mã ASCII và xuất ký tự. Không thay đổi giá trị của bộ tích lũy.

Nếu bộ tích lũy lớn hơn 255, chương trình sẽ trả về lỗi. Tương tự như vậy nếu tích lũy nhỏ hơn 0.

Đánh số

o

Xuất ra giá trị của bộ tích lũy. Không thay đổi giá trị của bộ tích lũy.

Tăng

^

Tăng tích lũy thêm một.

Giảm bớt

v

Giảm tích lũy thêm một.

Thêm vào

+x

Đặt bộ tích lũy thành giá trị của bộ tích lũy cộng với giá trị của x.

Trừ

-x

Đặt bộ tích lũy thành giá trị của bộ tích lũy trừ đi giá trị của x.

nhân

*x

Đặt bộ tích lũy thành giá trị của bộ tích lũy nhân với giá trị của x.

Chia

/x

Đặt bộ tích lũy thành giá trị của bộ tích lũy chia cho giá trị của x. (Lưu ý rằng đây là phép chia số nguyên, do đó, 1/6kết quả là 0)

Con số

n

Đặt bộ tích lũy thành số nguyên n.

chú thích

Ở đây, xncó thể là bất kỳ số nguyên từ 0để 2^32-1toàn diện.

Thêm thông tin

Bạn chỉ phải sử dụng các toán tử được mô tả ở trên. Do đó, chương trình Fourier xuất ra của bạn không hợp lệ nếu nó sử dụng bất kỳ điều nào sau đây (lưu ý rằng các toán tử sau được phép cho tiền thưởng):

  • Lặp lại các vòng lặp
  • Nếu báo cáo
  • Biến
  • Ngẫu nhiên
  • Modulo
  • Đầu vào của người dùng
  • Lớn hơn / ít hơn các nhà khai thác
  • Toán tử bình đẳng
  • Xóa màn hình
  • Thời gian trễ
  • Hàm ngày

Chương trình của bạn có thể là một chương trình đầy đủ hoặc một hàm, nhận đầu vào thông qua STDIN, một đối số tệp hoặc hàm. Bạn cũng có thể lấy đầu vào trực tiếp từ Internet.

Lưu ý rằng nếu có một vvmã trong mã của bạn, bạn nên thay thế nó bằng -2. Tương tự như vậy ^^, thay thế nó bằng +2.

Ví dụ

Nếu đầu vào là 7n, thì chương trình dự kiến ​​là:

55a110a

Nhưng bạn có thể lưu một byte với

55a*2a

Một cách khác là

7o110a

Sử dụng số ra.


Tương tự nếu đầu vào là Hello, thì chương trình dự kiến ​​là:

72a101a108a108a111a

Bạn có thể đánh gôn xuống 3 byte (vì đầu ra không thay đổi bộ tích lũy):

72a101a108aa111a

Nhưng chờ đã, chúng ta có thể sử dụng toán tử cộng, tiết kiệm 2 byte:

72a101a+7aa+3a

Định dạng

Bởi vì tôi sẽ sử dụng bảng xếp hạng Stack Snippet của Martin Büttner, vui lòng bạn có thể định dạng tiêu đề như vậy:

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

Sau đó, bạn có thể đặt bất cứ điều gì bạn muốn dưới tiêu đề.

Chiến thắng

Bạn nên đăng độ dài của các chương trình Fourier (được tạo bởi mã của bạn) để xuất tệp văn bản nàytệp văn bản này . Điểm của bạn là độ dài kết hợp của cả hai chương trình Fourier tính bằng byte (các ký tự không phải ASCII không được sử dụng trong Fourier để nó không thực sự tạo ra sự khác biệt).

Người có điểm thấp nhất sẽ thắng. Nếu có hòa, chương trình ngắn nhất tính bằng byte sẽ thắng.

Tiền thưởng

Tiền thưởng 500 rep này là cho một câu trả lời mới , đó là đánh gôn bằng cách sử dụng bất kỳ chức năng nào của Fouri. Điều đó bao gồm các biến, vòng lặp và nếu câu lệnh, vv Câu trả lời mới này sẽ không được chấp nhận.

Bảng xếp hạng

Tham khảo phần định dạng ở trên:

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
Tôi không nghĩ rằng phải đưa ra tất cả các giải pháp tối ưu là rất công bằng / thú vị. Nó loại trừ tất cả các thực thi ngoại trừ lực lượng vũ phu ...
orlp

5
Vấn đề thực sự với việc phải đưa ra tất cả các giải pháp tối ưu là với một đầu vào dài, sẽ có nhiều giải pháp tối ưu hơn sau đó có các nguyên tử trong vũ trụ.
isaacg

1
@orlp Đã chỉnh sửa xuất ra tất cả các giải pháp tối ưu
Beta Decay

1
Nó chỉ nên được in ASCII, hoặc bất kỳ loại ASCII nào? Và chỉ có ASCII 7 bit, hoặc byte đầy đủ?
orlp

1
Bộ tích lũy có bắt đầu từ 0 không?
ASCIIThenANSI

Câu trả lời:


9

Python, 14307118 byte

601216 cho Hamlet + 13705902 cho Genesis = 14307118

Chắc chắn có một số kịch bản mà theo đó giải pháp này không tối ưu, chẳng hạn như 1111, nơi nó sẽ xuất ra 1111otrái ngược với 11oo. Tuy nhiên, tôi nghĩ nó gần như tối ưu.

Chỉnh sửa: Đã lưu một vài byte bằng cách cải thiện 0o0othành 0oo.

Tên của tệp chứa đầu vào được nhận trên STDIN, đầu ra thành STDOUT.

Kết quả xác minh với thông dịch viên chính thức.

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 Chà, tôi khá chắc chắn kết quả của Geobit là sai, hãy xem ý kiến ​​của tôi ở đó.
isaacg

Có rất ít trong đó, nhưng bạn đã giành được chỉ với 5 ký tự (bạn và Razvan bị ràng buộc nên tôi đã sử dụng độ dài mã của bạn làm bộ bẻ khóa)
Beta Decay

2
@BetaDecay Tôi chưa bao giờ thấy bộ bẻ khóa dài có liên quan giữa một cặp chương trình chưa được chỉnh sửa trước đó.
isaacg

Ừ ... Tôi cũng vậy: P
Beta Decay

13

> <>, 14310665 byte

601398 cho ấp + 13709267 cho genesis

Đây vẫn là một công việc đang tiến triển và mất rất nhiều thời gian để hoàn thành.

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

Điều đó thật nhỏ bé, thật xấu hổ vì nó không tối ưu.
orlp

Tôi đang làm việc bằng cách sử dụng /, * và o, nhưng nó bắt đầu có thêm một số vị trí.
Aaron

18
Không sao đâu, cá thường phát triển theo từng câu chuyện;)
Geobits 27/08/2015

Chà, đây là một sự lựa chọn tuyệt vời về ngôn ngữ: D
Beta Decay

Chương trình của bạn không phù hợp với tiêu chí cho tiền thưởng (không có câu trả lời nào được đăng), vì vậy tôi đã trao phần thưởng này cho bạn vì tôi thích rằng bạn đã sử dụng <> <.
Beta Decay

8

Java, 14307140 byte

Ấp - 601,218

Sáng thế ký - 13,705,922

Ý tưởng ở đây là thực hiện tất cả các công việc trước, bằng cách tạo một ký tự-> bản đồ nhân vật. Sau đó, bạn có thể chỉ cần lặp qua và lấy các chuỗi ngắn nhất.

Một chút ngoại lệ phải được thực hiện cho các chữ số, vì vậy tôi kiểm tra chúng trong vòng lặp chính. Mặc dù vậy, nó vẫn nhanh và xử lý trường hợp thử nghiệm lớn hơn trong vài giây. Tôi thể điều chỉnh phần này thêm một vài byte, nhưng tôi khá chắc chắn rằng nó gần tối ưu.

Đầu vào là một tên tệp làm đối số. Đầu ra được ghi vào một tệp inputFilename_out.4và số ký tự được gửi đến STDOUT.

Đây là 1737 byte cho bộ bẻ khóa, hoàn toàn không được chỉnh sửa. Tôi có thể chơi golf rất nhiều nếu cần, nhưng nó vẫn sẽ hơi lớn.

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

}

Tôi nghĩ rằng điều này không xử lý các chuỗi chữ số với các số 0 đứng đầu một cách chính xác. Ví dụ, về đầu vào 01, tôi tin rằng nó xuất ra 01o, điều này không đúng.
isaacg

Ngoài ra, tôi nghĩ rằng bạn đang lạm dụng bộ tích lũy. Trong elsemệnh đề của vòng lặp chính, bạn chọn giữa việc sử dụng giá trị thực của bộ tích lũy và giá trị ký tự của ký tự trước đó. Bạn không thể đưa ra lựa chọn sau nếu hai cái khác nhau, vì điều đó có nghĩa là bạn đã sử dụng othời gian trước đó và bộ tích lũy không chứa giá trị của ký tự trước.
isaacg

Phải, cả hai nên được sửa chữa ngay bây giờ. Cảm ơn!
Geobits 27/8/2015

Khi tôi chạy cái này trên máy của mình, tôi nhận được 625474 cho Hamlet và 13705922 cho Genesis.
isaacg

@isaacg Bạn có đang chạy nó trên cùng một tệp (có cùng dòng kết thúc) không? Tôi gặp vấn đề với kết thúc dòng trước đó. Khi tôi chạy của tôi và của bạn trên cùng một tệp, cả hai đều hiển thị điểm số đã đăng.
Geobits 27/8/2015

2

PHP, 14307118 byte

601,216 (Ấp) + 13,705,902 (Kinh thánh)

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

Đầu ra Fourier cho Hamlet

Nó hoạt động như sau:

  1. Lặp lại qua từng ký tự trong đầu vào;
  2. Nếu có một chuỗi các chữ số không có 0, nó sẽ đặt bộ tích lũy thành số đó và xuất nó thành số. Nó cũng kiểm tra các chữ số tương tự;
  3. Mặt khác, kiểm tra xem có cách nào ngắn hơn để xuất ký tự hiện tại (thay vì mã ASCII + "a" ký hiệu = 4 ký tự) bằng cách thực hiện thao tác cơ bản (+ - * /) trên bộ tích lũy có số từ 2 đến 9; rõ ràng, nó cũng cố gắng so sánh / tăng / giảm;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.