Her ASCII karakterini 99'da golf oynamak


11

99 , bu haftanın başlarında meydan okumam için icat ettiğim bir programlama dilidir . 99 için bir tercüman yaz . (Yarım düzine sayınız sayesinde icat edilmiş ama hiç bir zaman gerekli olmamıştı.)) Tam dil spesifikasyonu bu zorlukta, bu yüzden hepsini burada tekrar yayınlamak için uğraşmıyorum.

In 99 tek tek yazdırabilirsiniz ASCII Stdout'a karakterleri, fakat dilin kısıtlamaları nedeniyle, her zaman kısaca mümkün olduğunca belirli bir karakteri nasıl yazdırılacağını belli değil.

128 ASCII karakterinin her biri için , hiç girdi almayan ve o karakteri çıkaran 99 program yazın. Bu cevapların herhangi birini veya tümünü elle kodlayabilir veya sizin için oluşturmak üzere başka bir program (istediğiniz herhangi bir dilde) yazabilirsiniz.

128 99 programınızın her birindeki karakterlerin toplamı sizin puanınızdır. En düşük puan kazanır. Yeni satırlar bir karakter olarak sayılır.

99'da , yalnızca 9999çıkış ASCII karakterleri (tek boyutlu değişkenler çıkış tamsayıları) gibi boyutlandırılmış değişkenleri bile unutmayın . Değerleri 9'a bölünür ve sonra mod 128 alınır, bu nedenle ASCII karakterleriyle eşleştirmek için değerlerin belirli bir aralıkta olması gerekmez. Örneğin, 297, 1449 ve -855 dahili değerlerinin tümü karaktere karşılık gelir, !çünkü 9'a bölündüklerinde ve mod 128 alındığında hepsi 33 olur, bu da karakter kodudır !.

99 için bir tercümana ihtiyacınız varsa , Mac'in Python cevabını öneririm .

Biliyorum dedim sonraki zorluk daha interaktif olacak ama yine de o biri için malzeme üzerinde çalışıyorum.

Yanıtlar:


7

Bir ödev, 2075 (optimal)

Bu en uygun değer olmalıdır (akıl yürütmede büyük bir hatam yoksa veya testim berbat değilse).

Her şeyden önce. 99 olarak ifade edebileceğiniz yalnızca 7 farklı sayı (mod 128) vardır. 7 veya daha fazla 9'un tüm değerleri aynı sayı 71'e eşittir. (10 ^ 8 mod 128 == 0, 10 ^ 9 mod 128 == 0, ...)

4 değerden biri eşit sayıda dokuzla ifade edebiliyorsanız, bu sayının çıktısını almak en uygun çözümdür.

Aksi takdirde bir atama ifadesi ile sayıya ulaşmaya çalışıyorum (99'a ata) ve 99 yazdım. Bu yaklaşımla maksimum program boyutu ortaya çıktığında 22 karakter. Açıkça Goto kullanmak kesinlikle bundan daha fazlasını gerektirir. Tek atama çözümünün yenilebilmesi için tek olasılık iki atama içeren bir çözümdür. Bunu test ettim (umarım hiçbir hata olmadan, bunun kodu oldukça dağınıktır) ve herhangi bir ASCII char için çözüm bulamadım.

Bu nedenle, en iyi çözümü bulmak için sadece 4 doğrudan sayıyı ve tek atama yaklaşımını kontrol etmek yeterli olmalıdır. Aşağıdaki Python (2 ve 3 uyumlu) programı tüm programları oluşturur ve uzunluklarını toplar. Basit bir IDA * yaklaşımı kullanır.

from itertools import count

def nines_to_dec(nines):
    return ((10**nines - 1) // 9) % 128

def shortest_representation(ascii_value):
    # try simple output,
    # max code length is 8, (8 nines == 10 nines == 12 nines == ...)
    # if this works, than this is the shortest representation

    for nines in range(2, 9, 2):
        if nines_to_dec(nines) == ascii_value:
            return "9" * nines

    # otherwise try one assignment
    for length in count(1):
        result = assignment(ascii_value, length, [])
        if result:
            return "99 " + result + "\n99"

def assignment(value, left, nines_list):
    if left == 0:
        eval_numbers = [nines_to_dec(nines) for nines in nines_list]

        if (sum(eval_numbers[::2]) - sum(eval_numbers[1::2])) % 128 == value:
            return " ".join("9" * nines for nines in nines_list)
        else:
            return False

    for nines in range(1, 8):
        left2 = left - nines - 1 # -1 for space
        if left2 >= 0:
            result = assignment(value, left2, nines_list + [nines])
            if result:
                return result

    return False

lengths = []
for i in range(128):
    program =shortest_representation(i)
    lengths.append(len(program))
    print("ASCII-value: {}, ASCII-char: {}".format(i, chr(i)))
    print(program)

print(sorted(lengths))
print(sum(lengths))

Çıktı aşağıdaki biçimdedir:

....
ASCII-value: 65, ASCII-char: A
99 9 999999 9999999
99
ASCII-value: 66, ASCII-char: B
99 9 99 9999 99
99
ASCII-value: 67, ASCII-char: C
99 9 99 9 99 9999
99
....

Çıktının tamamını şu adreste bulabilirsiniz: http://pastebin.com/bKXLAArq

Kısa programı (2 char) ile char vertical tab - 112'nin bir program uzunluğu, uzun programların (22 karakter) ile karakter olan bell - 7ve A - 65.

Tüm programların toplamı 2075'tir.

Bu arada, tmartin'den k / q yorumlayıcısını kullandım . Diğerleriyle oldukça sıkıntı çekiyorum (Python, Perl, CJam). Benim hatam olup olmadığından emin değilim.


Ne tür sıkıntılarınız olduğunu açıklayabilirseniz, tercüman uygulayıcılarına yardımcı olacaktır. Mükemmel cevap.
coredump

3

Çeşitli Teknikler, 42109

Sayılar için, büyük ASCII karakterini hesaplamak yerine, sadece sayının değerini hesapladım. Siz sadece karakteri çıkarabileceğinizi söylediniz, bu hala işe yarayacak.

EDIT: ASCII karakterlerini kullanmak için sayıları değiştirdi, bu yüzden dikkate almayın. Orijinal numara kodunu Java kodunda bıraktım, ancak herhangi birinin kullanmak istemesi durumunda yorum yaptım.

Bunlardan bazıları el ile yaptım, çoğu sadece yazmak için bir program yazdım.

Bunların her biri 1-4 satırdan oluşur, bu nedenle bir programa kopyalayıp yapıştırmak oldukça kolaydır. Oluşturulan kodum değişken durumlarını korumadıkları için art arda çalışmazlar.

Burada kullanılan en yaygın teknik, orlp'nin yaklaşımıyla aynıydı:

99'dan 9 çıkarmaya devam edin, sonra çıktı alın.

Sürümüm, bazı özel durumlar kullanarak ve matematiğin çoğunu tek bir satıra yazarak farklılık gösterir. Özel durumlar, karakterin sadece 9'luk bir grupla temsil edilebildiği yerlerdir ve hiçbir matematik veya üretim kodum kısaltılamaz.

Programlar

Programı çalıştırmak istemeyenleriniz için çıktıyı Pastebin'e koydum:

http://pastebin.com/Cs6WZUfb

Kullandığım Java Kodu:

public class AsciiGen99 {

  public static void main(String[] args) {
    long totalsize = 0;
    for (int i = 0; i < 128; i++) {
      System.out.println("\n The program for ASCII code " + i + " is as follows:\n");
      String yea = find(i);
      if (yea != null) {
        System.out.println(yea);
        totalsize += yea.length();
      } else {
        String v = "99 9 9\n9 99 9";
        if (i != 0) {
          v += "\n99";
          for (int j = 0; j < i; j++) {
            v += " 99 9";
          }
        }

        v += "\n99";

        System.out.println(v);
        totalsize += v.length();
      }
    }
    System.out.println(totalsize);
  }

  public static String find(int i) {
    switch (i) {
      case '\0':
        return "99 9 9\n99";
      case '\1':
        return "99 9\n99";
    }
//    if (48 <= i && i <= 57) {
//      switch (i) {
//        case '0':
//          return "9 9 9\n9";
//        case '1':
//          return "9";
//        case '2':
//          return "999 9 9\n9 999 9\n999 999 9 999 9\n999";
//        case '3':
//          return "999 9 9\n9 999 9\n999 999 9 999 9 999 9\n999";
//        case '4':
//          return "999 9 9\n9 999 9\n999 999 9 999 9 999 9 999 9\n999";
//        case '5':
//          return "999 9 9\n9 999 9\n999 999 9 999 9 999 9 999 9 999 9\n999";
//        case '6':
//          return "99 9 9\n9 99 9\n999 99 9 99 9 99 9 99 9 99 9 99 9\n999";
//        case '7':
//          return "99 9 9\n9 99 9\n999 99 9 99 9 99 9 99 9 99 9 99 9 99 9\n999";
//        case '8':
//          return "99 9 9\n9 99 9\n999 99 9 99 9 99 9 99 9 99 9 99 9 99 9 99 9\n999";
//        case '9'://ironic
//          return "99 9 9\n9 99 9\n999 99 9 99 9 99 9 99 9 99 9 99 9 99 9 99 9 99 9\n999";
//      }
//    }
    int x, a;
    for (x = 0; x < 100000; x++) {
      a = i + 128 * x;
      String s = "" + a*9;
      if (containsOnly9(s) && (s.length() & 1) == 0) {
        return ("" + (a * 9));
      }
    }

    return null;
  }
  public static boolean containsOnly9(String s) {
    for (char c : s.toCharArray()) {
      if (c != '9' && c != ' ' && c != '\n' && c != '\r' && c != '\t') {
        return false;
      }
    }
    return true;
  }
}

Sadece sayıyı değil, karakteri de çıktılamak zorundasınız. Bu yüzden 999sonunda tüm programların düzeltilmesi gerekiyor.
Calvin'in Hobileri

Ah, tamam o zaman, bunu birazdan çözeceğim.
bloo

Bir şey kaçırmadıkça şimdi düzeltilmelidir. Orijinal kodu bıraktım ama birisi bu gibi numaraları kullanmak istemesi durumunda yorum yaptı. Pastebin de düzenlendi.
bloo

Harika. Bazıları için sadece eklediğinizi düşünüyorum 99 999\n99(yeniden atamak 999için 99bir karakter olarak yazdırmak için).
Calvin'in Hobileri

1

Tekrarlanan çıkarma, 65280

Karşılaştırma yapmak için önemsiz bir çözüm. 99'dan 9 çıkarmaya devam edin, sonra çıktı alın. ASCII karakter 10 için örnek:

99 99 9
99

128 program var. İlk program iki karakter uzunluğundadır (99), her biri bir öncekinden 8 karakter (99 99 9 \ n) daha uzundur.

Boş satırlarla ayrılmış programlar üreten Python programı ve hesaplama puanı:

score = 0
for n in range(128):
    program = "99 99 9\n" * n + "99"
    score += len(program)
    print(program + "\n")

print(score)
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.