フーリエのゴルフ弦


24

チャレンジ

入力として文字列を指定すると、その文字列を出力するフーリエプログラムをたどります。

フーリエでは、文字列を出力する簡単な方法はありません。各文字コードを調べて、文字として出力する必要があります。

フーリエ

この言語は、プログラムの開始時に0に初期化されるグローバル変数であるアキュムレーターに基づいています。これは、言語のほぼすべての演算子で使用されます。アキュムレータの値を変更しないのは一部のみです。

キャラクターアウト

a

アキュムレータの値をASCIIコードとして取得し、文字を出力します。アキュムレーターの値を変更しません。

アキュムレータが255より大きい場合、プログラムはエラーを返します。同様に、アキュムレーターが0より小さい場合。

番号アウト

o

アキュムレータの値を出力します。アキュムレーターの値を変更しません。

増加する

^

アキュムレーターを1つ増やします。

減少

v

アキュムレータを1つ減らします。

追加する

+x

アキュムレータにxの値を加えた値にアキュムレータを設定します。

引く

-x

アキュムレータの値からxの値を引いた値にアキュムレータを設定します。

かける

*x

アキュムレータにxの値を掛けた値にアキュムレータを設定します。

割る

/x

アキュムレータをxの値で除算した値にアキュムレータを設定します。(これは整数除算であるため、1/6結果はになります0

n

累算器を整数nに設定します。

注意

ここでxnはから0までの任意の整数2^32-1です。

詳しくは

上記の演算子のみを使用する必要があります。したがって、次のいずれかを使用する場合、出力されるフーリエプログラムは無効になります(次の演算子が報奨金に許可されていることに注意してください)。

  • 繰り返しループ
  • Ifステートメント
  • 変数
  • ランダム
  • モジュロ
  • ユーザー入力
  • 演算子よりも大きい/少ない
  • 平等演算子
  • 画面をクリア
  • 時間遅延
  • 日付関数

プログラムは、完全なプログラムまたは関数のいずれかであり、STDIN、ファイルまたは関数の引数を介して入力を受け取ります。インターネットから直接入力することもできます。

vvコードにがある場合は、に置き換える必要があることに注意してください-2。同じことが起こり^^、それをに置き換え+2ます。

入力がの場合、7n予想されるプログラムは次のとおりです。

55a110a

しかし、あなたは1バイトを節約することができます

55a*2a

別の方法は

7o110a

番号を使用します。


同様に、入力がの場合、Hello予想されるプログラムは次のとおりです。

72a101a108a108a111a

それを3バイトずつゴルフダウンすることができます(出力してもアキュムレータが変更されないため):

72a101a108aa111a

ただし、追加演算子を使用して2バイトを節約できます。

72a101a+7aa+3a

書式設定

MartinBüttnerのStack Snippetリーダーボードを使用するため、タイトルを次のようにフォーマットしてください。

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

次に、タイトルの下に好きなものを置くことができます。

勝ち

このテキストファイルこのテキストファイルを出力するには、(プログラムで作成された)フーリエプログラムの長さを投稿する必要があります。スコアは両方のフーリエプログラムの長さをバイト単位で組み合わせたものです(非ASCII文字はフーリエでは使用されないため、実際には違いはありません)。

最も低いスコアを持つ人が勝ちます。同点の場合、バイト単位の最短プログラムが勝ちます。

バウンティ

この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&]*(?:&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

1
@orlpすべての最適なソリューションの出力を編集
Beta Decay

1
印刷可能なASCIIのみ、または任意の種類のASCIIである必要がありますか?そして、7ビットASCIIのみ、またはフルバイト?
orlp

1
アキュムレーターは0から始まりますか?
ASCIIThenANSI

回答:


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

その中にはほとんど何もありませんでしたが、わずか5文字で勝ちました(あなたとRazvanが結んだので、コードの長さをタイブレーカーとして使用しました)
ベータディケイ

2
@BetaDecay私は、長さのタイブレーカーが一対の非ゴルフ番組の間に関連するのを見たことがありません。
isaacg

うん...私も:P
ベータ崩壊

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

D:まあ、これは言語の華麗な選択肢である
ベータ崩壊

あなたのプログラムは賞金の基準に適合しませんでした(投稿された回答はどれも当てはまりませんでした)。
ベータ崩壊

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

}

これは、先行ゼロを含む数字の文字列を正しく処理しないと思います。たとえば、入力では01、私はそれが出力01oであると信じていますが、これは正しくありません。
-isaacg

また、アキュムレータを誤用していると思います。ではelse、メインループの句は、アキュムレータの実際の値と前の文字の文字値を使用するかを選択しました。2つが異なる場合、後者の選択を行うことはできませんo。これは、以前の時間を使用したことを意味し、アキュムレーターには前の文字の値が含まれていないためです。
isaacg

両方とも今すぐ修正する必要があります。ありがとう!
ジオビット

これを自分のマシンで実行すると、ハムレットで625474、ジェネシスで13705922が得られます。
isaacg

@isaacg同じファイルで(同じ行末で)実行していますか?先ほど行末の問題に遭遇しました。私とあなたのファイルを同じファイルで実行すると、両方とも投稿されたスコアを表示します。
ジオビット

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

Hamletのフーリエ出力

次のように機能します。

  1. 入力内の各文字を反復処理します。
  2. 先頭に0以外の数字のシーケンスがある場合、アキュムレータをその数値に設定し、数値として出力します。同様の数字もチェックします。
  3. それ以外の場合、2〜9の数のアキュムレータで基本操作(+-* /)を実行することにより、現在の文字を出力するより短い方法(ASCIIコード+ "a"シンボル= 4文字ではなく)があるかどうかをチェックします。明らかに、比較/増分/減分も試みます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.