Fourier'de golf oynamak


24

Meydan okuma

Girdi olarak bir dize verildiğinde, o dizgeyi çıkaran Fourier programında golf oynayın.

Fourier'de bir dizgeyi çıkarmanın kolay bir yolu yoktur: her karakter kodundan geçmeniz ve bunu bir karakter olarak çıkarmanız gerekir.

Fourier

Dil, programın başlangıcında 0'a ilklendirilen global bir değişken olan bir akümülatöre dayanmaktadır. Bu, dildeki hemen hemen her operatör tarafından kullanılır. Sadece birkaçı akümülatörün değerini değiştirmez.

Karakter

a

Akümülatörün değerini ASCII kodu olarak alır ve karakteri verir. Akümülatörün değerini değiştirmez.

Akümülatör 255'ten büyükse, program bir hata verecektir. Aynı şekilde, akümülatör 0'dan az ise.

Sayı

o

Akümülatörün değerini verir. Akümülatörün değerini değiştirmez.

Artırmak

^

Akümülatörü birer birer arttırın.

Azaltmak

v

Akümülatörü bir azaltın.

Eklemek

+x

Akümülatörü, akümülatör değerine artı x değerine ayarlar.

çıkarmak

-x

Akümülatörü, akümülatörün değerine eksi x değerine ayarlar.

Çarpmak

*x

Akümülatörü, akümülatörün değerine x değeri ile çarpılan değere ayarlar.

bölmek

/x

Akümülatörü, akünün değerine bölerek x değerine ayarlar. (Not: Bu bölünme tamsayıdır, bu yüzden 1/6sonuçları 0)

Numara

n

Akümülatörü n tamsayısına ayarlayın.

Not

Burada, xve nherhangi bir tamsayı olabilir 0için 2^32-1kapsayıcı.

Daha fazla bilgi

Sadece yukarıda açıklanan operatörleri kullanmalısınız. Bu nedenle, çıkarılan Fourier programınız aşağıdakilerden herhangi birini kullanıyorsa geçersizdir (aşağıdaki operatörlerin lütuf için izin verildiğini unutmayın):

  • Döngüleri tekrarla
  • Eğer ifadeler
  • Değişkenler
  • rasgele
  • Modülo
  • Kullanıcı girişi
  • Operatörlerden daha büyük / daha az
  • Eşitlik operatörleri
  • Temiz ekran
  • Zaman gecikmesi
  • Tarih fonksiyonları

Programınız, STDIN, bir dosya veya fonksiyon argümanları üzerinden giriş yaparak tam bir program veya fonksiyon olabilir. Ayrıca doğrudan İnternet'ten de giriş yapabilirsiniz.

Bir varsa unutmayın vvkodunuzda, sen ile değiştirmek gerekir -2. Aynı şey ^^, bununla değiştirilir +2.

Örnekler

Girdi ise 7n, beklenen program şudur:

55a110a

Ancak bir bayt ile kaydedebilirsiniz.

55a*2a

Başka bir yol

7o110a

Sayı kullanımı.


Benzer şekilde, eğer girdi ise Hello, beklenen program şudur:

72a101a108a108a111a

3 byte kadar golf oynayabilirsiniz (çünkü çıktı akümülatörü değiştirmez):

72a101a108aa111a

Fakat bekleyin, toplama operatörünü kullanabiliriz, 2 byte tasarruf ederek

72a101a+7aa+3a

Biçimlendirme

Martin Büttner'ın Yığın Snippet lider panosunu kullanacağım için lütfen başlığı şöyle biçimlendirir misiniz:

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

Ardından, istediğiniz herhangi bir şeyi başlığın altına koyabilirsiniz.

Kazanan

Bu metin dosyasını ve bu metin dosyasını çıkarmak için Fourier programlarının uzunluğunu (kodunuz tarafından üretilen) göndermelisiniz . Puanınız her iki Fourier programının bayt cinsinden toplam uzunluğudır (ASCII olmayan karakterler Fourier'de kullanılmaz, bu nedenle gerçekten bir fark yaratmaz).

En düşük puan alan kişi kazanır. Bir bağ varsa, bayt cinsinden en kısa program kazanır.

cömertlik

Bu 500 rep ödül, Fourier'in işlevlerinden herhangi birini kullanarak dizeleri golf yapan yeni bir cevap içindir. Bu değişkenler, döngüler ve eğer ifadeler vs. içeriyorsa.

Liderler Sıralaması

Yukarıdaki biçimlendirme bölümüne bakı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üm optimal çözümleri üretmek zorunda kalmanın çok adil / ilginç olduğunu düşünmüyorum. Kaba kuvvet hariç tüm uygulamaları
dışlar

5
Tüm en uygun çözümleri üretmek zorunda kalmanın asıl sorunu, uzun bir girdi için, evrende atomlar bulunduğundan daha uygun çözümler elde edilmesidir.
isaacg,

1
@orlp Tüm optimum çözümleri üreterek çıktı
Beta Decay

1
Yalnızca yazdırılabilir ASCII mi, yoksa herhangi bir ASCII mi olmalı? Ve sadece 7 bit ASCII veya tam bayt?
orlp

1
Akümülatör 0'da mı başlıyor?
ASCIIThenANSI

Yanıtlar:


9

Python, 14307118 bayt

Hamlet için 601216 + Genesis için 13705902 = 14307118

Kesinlikle, bu çözümün, bunun yerine çıktığı 1111yerlerde olduğu gibi, optimal olmadığı bazı senaryolar vardır 1111o.11oo . Ancak, neredeyse optimal olduğunu düşünüyorum.

Düzenleme: geliştirerek birkaç byte Kaydedilen 0o0oiçin 0oo.

Girdiyi içeren dosyanın adı STDIN'de, STDOUT'da çıktı olarak alınır.

Sonuçlar resmi tercüman ile doğrulandı.

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 Peki, Geobit'in sonucunun yanlış olduğundan eminim, yorumlarımı gör.
isaacg,

İçinde çok az vardı, ama sen sadece 5 karakter kazandın (sen ve Razvan bağladığın için kod uzunluğunu tiebreaker olarak kullandım)
Beta Decay

2
@BetaDecay Daha önce hiç bir çift ağzı açılmış program arasında tiebreaker ile ilgili uzunluk hiç görmedim.
isaacg

Evet ... Ben de: P
Beta Çürümesi

13

> <>, 14310665 bayt

Hamlet için 601398 + genesis için 13709267

Bu hala devam eden bir çalışma ve tamamlanması çok zaman alıyor.

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

Bu küçük, utanç verici olsa da optimal değil.
orlp

/, * Ve o kullanarak çalışıyorum, ancak daha fazla yer almaya başladı.
Aaron,

18
Sorun değil, balık normalde her bir hikaye anlatırken büyür;)
Geobits

Bu harika bir dil seçimi: D
Beta Decay,

Programınız ödül kriterlerine uymuyordu (gönderilen cevapların hiçbiri yapmadı), bu yüzden bunu size verdim çünkü <> <kullanmasını seviyorum.
Beta Çürüğü

8

Java, 14307140 bayt

Hamlet - 601,218

Genesis - 13.705.922

Buradaki fikir, tüm işi baştan sona bir karakter-> karakter haritası yaparak yapmak. Sonra sadece döngü ve en kısa dizeleri yakalayabilirsiniz.

Rakamlar için bir miktar istisna yapılması gerekir, bu yüzden ana döngüde onları kontrol ederim. Yine de hızlı ve büyük test senaryosunu birkaç saniye içinde halledebiliyor. Ben may bir çift daha bayt için bu bölümü oynamak mümkün, ama oldukça emin optimuma yakın ediyorum.

Girdi, bağımsız değişken olarak bir dosya adıdır. Çıktı bir dosyaya yazılır inputFilename_out.4ve karakter sayısı STDOUT'a gönderilir.

Bu tiebreaker için 1737 bayttır, tamamen iç içe geçmiştir. Gerekirse golf oynayabilirim ama yine de biraz büyük olacak.

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

}

Sanırım bu, baştaki sıfıra sahip basamak dizelerini doğru şekilde işlemiyor. Örneğin, girişte 01, bunun 01odoğru olmadığına inanıyor .
isaacg,

Ayrıca, akümülatörü yanlış kullandığınızı düşünüyorum. Gelen elseana döngünün maddesi, biriktiricide gerçek değerini ve önceki karakterin karakter değerini kullanarak arasında seçim. İkisi farklıysa, ikinci seçimi yapamazsınız, çünkü bu, oönceki zamanı kullandığınız ve akünün önceki karakterin değerini içermediği anlamına gelir .
isaacg,

Doğru, her ikisi de şimdi düzeltilmelidir. Teşekkürler!
Geobits

Bunu makinemde çalıştırdığımda Hamlet için 625474, Genesis için 13705922 elde ediyorum.
isaacg,

@isaacg Aynı dosyada mı çalışıyorsunuz (aynı satır sonları ile)? Daha önce satır sonlarında bir sorunla karşılaştım. Ben ve seninkini aynı dosyada çalıştırdığımda, ikisi de kaydedilen puanları gösteriyor.
Geobits

2

PHP, 14307118 bayt

601,216 (Hamlet) + 13.705.902 (İncil)

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 için Fourier çıkışı

Aşağıdaki gibi çalışır:

  1. Girişteki her karakter üzerinde yinelenir;
  2. 0 önde gelen olmayan bir rakam dizisi varsa, akümülatörü bu sayıya ayarlar ve sayı olarak çıkarır. Aynı zamanda benzer rakamları kontrol eder;
  3. Aksi takdirde, akümülatör üzerinde 2 ile 9 arasında bir sayıyla temel bir işlem (+ - * /) yaparak geçerli karakteri (ASCII kodu + "a" sembolü = 4 karakter yerine) daha kısa bir şekilde çıkarmanın yolunu kontrol eder; Açıkçası, aynı zamanda / artım / azalış karşılaştırmaya çalışır;
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.