Normalleştirilmiş Malbolge - Malbolge çevirmeni


12

Bu görevde, Normalize Edilmiş Malbolge programını alan ve ortaya çıkan Malbolge'u çıkaran bir program / işlev yazacaksınız. programını . (Bu, tüm Malbolge programcılarının kullandığı gizli bir araçtır!)

Giriş

(Bir şekilde) Normalleştirilmiş Malbolge programını temsil eden bir veri yapısı.

Çıktı

Ortaya çıkan Malbolge programını temsil eden bir veri yapısı.

Örnekler

jpoo*pjoooop*ojoopoo*ojoooooppjoivvvo/i<ivivi<vvvvvvvvvvvvvoji
(=BA#9"=<;:3y7x54-21q/p-,+*)"!h%B0/.~P<<:(8&66#"!~}|{zyxwvugJ%

jjjj*<jjjj*<v
('&%#^"!~}{XE

jjjjjjjjjjjjjjjjjjjjjjj*<jjjjjjjjjjjjjjjjjjjjjjjj*<v
('&%$#"!~}|{zyxwvutsrqpnKmlkjihgfedcba`_^]\[ZYXWVT1|

Nasıl dönüştürülür?

Her karakter için aşağıdaki adımları uygulayarak normalize edilmiş Malbolge programı üzerinde tekrarlayın:

  1. Dizedeki *jpovi</karakterleri, içindeki ilgili karakterle değiştirin '(>DQbcu. (Yani, harita *için ', jiçin (, vb.)

  2. Ardından program sayacının geçerli konumunu (yani geçerli olandan önceki karakter sayısını) karakterin ASCII kodundan çıkarın.

  3. Ortaya çıkan ASCII kodu 33'ten küçükse 94 ile artırın ve en az 33 olana kadar tekrarlayın.

  4. Ortaya çıkan karakteri çıktıya ekleyin.

kurallar

  • Bu bir yarışmasıdır; en kısa cevap kazanır.
  • Standart boşluk yok lütfen.
  • Varsayılan G / Ç yöntemlerine izin verilir.
  • Giriş yalnızca karakter içerecektir *jpovi</.

4
Giriş yalnızca " *jpovi</" alanından karakterler içeriyor mu?
Joel

7
"O zaman, konum eksi" nin ne olduğunu anlamıyorum. anlamına geliyor. Muhtemelen sahte koddan anlayabilirdim, ancak açıklama kendi kendine yetmeli olmalıdır.
xnor

1
" Geçici Malbolge temsillerinin ASCII kodu 33'ten küçük olsa da, karakteri 94 arttırır. " Bununla ne demek istiyorsun? Zorluğu nasıl anladım: 1) harita karakterleri; 2) unicode değerine dönüştürmek; 3) her birini program sayacına göre azaltın (şimdi 'geçici Malbolge gösterimleri' ASCII kodu 'olarak adlandırdığınız şeye sahibiz); 4) herhangi bir değer 33'den küçükse, bunu 94 arttırın; 5) bu değerleri tekrar karakterlere dönüştürür. Ancak bu yaklaşımı kullanarak çıktı açıkça doğru değildir. Öyleyse, 33 karakterden daha uzun girdiler için bununla ne demek istediğinizi açıklığa kavuşturabilir misiniz?
Kevin Cruijssen

1
a: if ascii_code(temporary Malbolge representation) < 33: char := char + 94; goto a;

1
Malbolge'de bunlardan birini yazabilen herkese mutlu bir ödül vereceğim :)
JDL

Yanıtlar:


4

Jöle , 29 22 bayt

Oị“%þV DCµ2®  ‘_JịØṖḊ¤

Çevrimiçi deneyin!

Bir Jelly dizesini argüman olarak alan ve bir Jelly dizesini döndüren monadik bir bağlantı.

@JonathanAllan'a 2 bayt kazandığı için teşekkürler!

açıklama

O                      | Convert to Unicode code points
 ị“%þV DCµ2®  ‘        | Index into compressed integer list [37, 31, 86, 32, 68, 67, 9, 50, 8, 32, 32] (note the 32s are never actually used because the input mod 11 will be one of 1,2,3,5,6,7,8,9)
               _J      | Subtract position of character in original string
                 ị   ¤ | Index into the following as a nilad:
                  ØṖ   | - Printable ASCII characters
                    Ḋ  | - With the first character (space) removed

..._J‘ịØṖḊ¤bir bayt kaydeder.
Jonathan Allan

@JonathanAllan teşekkürler, iyi çağrı!
Nick Kennedy


6

Python 3 , 82 bayt

p=0
for c in input():print(end=chr((b"de{#0ABT"["*jpovi<".find(c)]-p)%94+33));p+=1

Çevrimiçi deneyin!

Bytestring'deki çirkin basılamaz karakterleri yazdırılabilir karakterlerle değiştirdiği için @Joel'e teşekkürler.

Değiştirmek için bir mod zinciri arıyorum "*jpovi<".find(c), ancak daha kısa bir tane olduğunu düşünmüyorum ve kapsamlı olmayan bir kaba kuvvet araması şu ana kadar bir şey bulamadı.

82 bayt

f=lambda s,p=0:s and chr((b"de{#0ABT"["*jpovi<".find(s[0])]-p)%94+33)+f(s[1:],p+1)

Çevrimiçi deneyin!


Yazdırılamayan ASCII karakterleri, daha iyi okunabilirlik için yazdırılabilir karakterlere dönüştürülecek şekilde 94 ile dengelenebilir.
Joel

Bunun b"de{#0ABT"["*jpovi<".find(c)]için bir programınız varsa eşlemenin yerini alacak bir matematik işlevi bulmayı deneyebilirsiniz .
Joel

1
@Joel Ne yazık ki, haritalamanın en azından sahip olduğum araçlarla aritmetik bir işlev için çok geniş bir arama alanı olduğunu düşünüyorum. Ben sadece x%84%15%7eşleme sağ yarısı gibi modulo zincirleri arıyorlardı , ama ben dahil *ve /terimleri aramak için başka bir meydan okuma için yazdım bazı kodu geri dönüşüm düşünüyorum .
xnor

@Joel %ve *( //Python 3'te muhtemelen buna değmez) kullanarak sağ taraf için mod-zincir tarzı bir şey bulamıyorum . Aslında, hiçbir şey 7 değerin ilk 6'sı ile eşleşmedi. Bunun işe yaramasını umdum çünkü kaba bir entropi tahmini muhtemelen% 7` ile biten yeterli ifade olduğunu söylüyor, ancak yakın. Ve belki de bu zincirler, eşit olarak dağıtılmaktan uzak çıktılar verir, özellikle de iki giriş aynı değere düştüğünde, başka hiçbir işlem bunları ayıramaz. Denediğim şeyler daha büyük ifadeyi aramak için hala çok aptal, ama herhangi bir fikriniz varsa, gidin.
xnor

Sanırım keyfi girişler için muhtemelen daha iyi bir algoritma gerekiyor map(ord, "*jpovi<"). Çıktı girişlerin çoğu için düzeni korumak etmezse (yani f(m)>=f(n)eğer m>=n), bazı özenle için sabitleri hazırlanmış %ve *muhtemelen ihtiyaç vardır ve bir kaba kuvvet arama olumlu sonuç elde etmek mümkün değildir.
Joel

6

Malbolge Bağlantısız (20-trit döndürme değişkeni), 7,784e6 bayt

Bu cevabın boyutu maksimum postalanabilir program boyutunu (eh) aşıyor, bu nedenle kod GitHub veri havuzumda bulunuyor .

Nasıl çalıştırılır?

Bu zor bir kısım olabilir, çünkü saf Haskell tercümanı bunu yapmak için çağlar alacaktır. TIO'nun iyi bir Malbogle Unshackled tercümanı var, ancak ne yazık ki kullanamıyorum (sınırlamalar).

Bulabildiğim en iyisi, çok iyi performans gösteren ve saniyede 0,5 karakter dönüştüren sabit 20 trit dönüş genişliği varyantıdır .

Tercümanı biraz daha hızlı hale getirmek için Matthias Lutter'in Malbolge Shackled yorumlayıcısından tüm kontrolleri kaldırdım.

Değiştirilmiş sürümüm yaklaşık% 6,3 daha hızlı çalışabilir.

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char* translation = "5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72Fh"
        "OA1CB6v^=I_0/8|jsb9m<.TVac`uY*MK'X~xDl}REokN:#?G\"i@";

typedef struct Word {
    unsigned int area;
    unsigned int high;
    unsigned int low;
} Word;

void word2string(Word w, char* s, int min_length) {
    if (!s) return;
    if (min_length < 1) min_length = 1;
    if (min_length > 20) min_length = 20;
    s[0] = (w.area%3) + '0';
    s[1] = 't';
    char tmp[20];
    int i;
    for (i=0;i<10;i++) {
        tmp[19-i] = (w.low % 3) + '0';
        w.low /= 3;
    }
    for (i=0;i<10;i++) {
        tmp[9-i] = (w.high % 3) + '0';
        w.high /= 3;
    }
    i = 0;
    while (tmp[i] == s[0] && i < 20 - min_length) i++;
    int j = 2;
    while (i < 20) {
        s[j] = tmp[i];
        i++;
        j++;
    }
    s[j] = 0;
}

unsigned int crazy_low(unsigned int a, unsigned int d){
    unsigned int crz[] = {1,0,0,1,0,2,2,2,1};
    int position = 0;
    unsigned int output = 0;
    while (position < 10){
        unsigned int i = a%3;
        unsigned int j = d%3;
        unsigned int out = crz[i+3*j];
        unsigned int multiple = 1;
        int k;
        for (k=0;k<position;k++)
            multiple *= 3;
        output += multiple*out;
        a /= 3;
        d /= 3;
        position++;
    }
    return output;
}

Word zero() {
    Word result = {0, 0, 0};
    return result;
}

Word increment(Word d) {
    d.low++;
    if (d.low >= 59049) {
        d.low = 0;
        d.high++;
        if (d.high >= 59049) {
            fprintf(stderr,"error: overflow\n");
            exit(1);
        }
    }
    return d;
}

Word decrement(Word d) {
    if (d.low == 0) {
        d.low = 59048;
        d.high--;
    }else{
        d.low--;
    }
    return d;
}

Word crazy(Word a, Word d){
    Word output;
    unsigned int crz[] = {1,0,0,1,0,2,2,2,1};
    output.area = crz[a.area+3*d.area];
    output.high = crazy_low(a.high, d.high);
    output.low = crazy_low(a.low, d.low);
    return output;
}

Word rotate_r(Word d){
    unsigned int carry_h = d.high%3;
    unsigned int carry_l = d.low%3;
    d.high = 19683 * carry_l + d.high / 3;
    d.low = 19683 * carry_h + d.low / 3;
    return d;
}

// last_initialized: if set, use to fill newly generated memory with preinitial values...
Word* ptr_to(Word** mem[], Word d, unsigned int last_initialized) {
    if ((mem[d.area])[d.high]) {
        return &(((mem[d.area])[d.high])[d.low]);
    }
    (mem[d.area])[d.high] = (Word*)malloc(59049 * sizeof(Word));
    if (!(mem[d.area])[d.high]) {
        fprintf(stderr,"error: out of memory.\n");
        exit(1);
    }
    if (last_initialized) {
        Word repitition[6];
        repitition[(last_initialized-1) % 6] =
                ((mem[0])[(last_initialized-1) / 59049])
                    [(last_initialized-1) % 59049];
        repitition[(last_initialized) % 6] =
                ((mem[0])[last_initialized / 59049])
                    [last_initialized % 59049];
        unsigned int i;
        for (i=0;i<6;i++) {
            repitition[(last_initialized+1+i) % 6] =
                    crazy(repitition[(last_initialized+i) % 6],
                        repitition[(last_initialized-1+i) % 6]);
        }
        unsigned int offset = (59049*d.high) % 6;
        i = 0;
        while (1){
            ((mem[d.area])[d.high])[i] = repitition[(i+offset)%6];
            if (i == 59048) {
                break;
            }
            i++;
        }
    }
    return &(((mem[d.area])[d.high])[d.low]);
}

unsigned int get_instruction(Word** mem[], Word c,
        unsigned int last_initialized,
        int ignore_invalid) {
    Word* instr = ptr_to(mem, c, last_initialized);
    unsigned int instruction = instr->low;
    instruction = (instruction+c.low + 59049 * c.high
            + (c.area==1?52:(c.area==2?10:0)))%94;
    return instruction;
}

int main(int argc, char* argv[]) {
    Word** memory[3];
    int i,j;
    for (i=0; i<3; i++) {
        memory[i] = (Word**)malloc(59049 * sizeof(Word*));
        if (!memory) {
            fprintf(stderr,"not enough memory.\n");
            return 1;
        }
        for (j=0; j<59049; j++) {
            (memory[i])[j] = 0;
        }
    }
    Word a, c, d;
    unsigned int result;
    FILE* file;
    if (argc < 2) {
        // read program code from STDIN
        file = stdin;
    }else{
        file = fopen(argv[1],"rb");
    }
    if (file == NULL) {
        fprintf(stderr, "File not found: %s\n",argv[1]);
        return 1;
    }
    a = zero();
    c = zero();
    d = zero();
    result = 0;
    while (!feof(file)){
        unsigned int instr;
        Word* cell = ptr_to(memory, d, 0);
        (*cell) = zero();
        result = fread(&cell->low,1,1,file);
        if (result > 1)
            return 1;
        if (result == 0 || cell->low == 0x1a || cell->low == 0x04)
            break;
        instr = (cell->low + d.low + 59049*d.high)%94;
        if (cell->low == ' ' || cell->low == '\t' || cell->low == '\r'
                || cell->low == '\n');
        else if (cell->low >= 33 && cell->low < 127 &&
                (instr == 4 || instr == 5 || instr == 23 || instr == 39
                    || instr == 40 || instr == 62 || instr == 68
                    || instr == 81)) {
            d = increment(d);
        }
    }
    if (file != stdin) {
        fclose(file);
    }
    unsigned int last_initialized = 0;
    while (1){
        *ptr_to(memory, d, 0) = crazy(*ptr_to(memory, decrement(d), 0),
                *ptr_to(memory, decrement(decrement(d)), 0));
        last_initialized = d.low + 59049*d.high;
        if (d.low == 59048) {
            break;
        }
        d = increment(d);
    }
    d = zero();

    unsigned int step = 0;
    while (1) {
        unsigned int instruction = get_instruction(memory, c,
                last_initialized, 0);
        step++;
        switch (instruction){
            case 4:
                c = *ptr_to(memory,d,last_initialized);
                break;
            case 5:
                if (!a.area) {
                    printf("%c",(char)(a.low + 59049*a.high));
                }else if (a.area == 2 && a.low == 59047
                        && a.high == 59048) {
                    printf("\n");
                }
                break;
            case 23:
                a = zero();
                a.low = getchar();
                if (a.low == EOF) {
                    a.low = 59048;
                    a.high = 59048;
                    a.area = 2;
                }else if (a.low == '\n'){
                    a.low = 59047;
                    a.high = 59048;
                    a.area = 2;
                }
                break;
            case 39:
                a = (*ptr_to(memory,d,last_initialized)
                        = rotate_r(*ptr_to(memory,d,last_initialized)));
                break;
            case 40:
                d = *ptr_to(memory,d,last_initialized);
                break;
            case 62:
                a = (*ptr_to(memory,d,last_initialized)
                        = crazy(a, *ptr_to(memory,d,last_initialized)));
                break;
            case 81:
                return 0;
            case 68:
            default:
                break;
        }

        Word* mem_c = ptr_to(memory, c, last_initialized);
        mem_c->low = translation[mem_c->low - 33];

        c = increment(c);
        d = increment(d);
    }
    return 0;
}

İşe yarıyor!

İşe yarıyor


2
Bu sadece delilik.
MilkyWay90

Yoldan geçenler için bayt sayısı 7.784 GB değil, 7.784 MB'dir. Virgülü başlangıçta ondalık basamak yerine binleri gruplama olarak yorumladım.
Potato44

@ Potato44 Polonya'da ondalık ayırıcı olarak virgül kullanıyoruz, nokta kullanmak yasaktır.
Krzysztof Szewczyk

5

Python 3 , 84 83 bayt

f=lambda p,i=0:p and chr(126-(i+b"WV@:-zyg"["*jpovi<".find(p[0])])%94)+f(p[1:],i+1)

Çevrimiçi deneyin!

Bu çoğunlukla hesaplamayı basitleştirmeyle ilgili bir matematik problemi ve ayrıca matematiği yaptıktan sonra golf oynamaktır. Kodun çözülmemiş versiyonu aşağıda gösterilmiştir.

Ungolfed, özyinelemesiz sürüm

def convert(prog):
    offsets = dict(zip("*jpovi</", [87, 86, 64, 58, 45, 122, 121, 103]))  # ASCII encoded to "WV@:-zyg"
    output = ""
    for pos, c in enumerate(prog):
        output += chr(126-(offsets[c]+pos)%94)
    return output

Çevrimiçi deneyin!


5

JavaScript (Node.js) , 69 bayt

s=>(B=Buffer)(s).map((c,i)=>33+(B(" #{T BAe0d")[c%11]+94-i%94)%94)+''

Çevrimiçi deneyin!

Nasıl?

Uygun bir şekilde, Malbolge komutları kolayca değerine dönüştürülebilir[1..9]11 .

 char. | ASCII code | mod 11
-------+------------+--------
  '*'  |      42    |   9
  'j'  |     106    |   7
  'p'  |     112    |   2
  'o'  |     111    |   1
  'v'  |     118    |   8
  'i'  |     105    |   6
  '<'  |      60    |   5
  '/'  |      47    |   3


3

05AB1E , 32 31 23 22 bayt

žQ¦•4¡ˆ¶ü]₁η₃•₃вIÇèā-è

-8 bayt NickKennedy'nin Jelly cevabının bir portunu oluşturuyor , bu yüzden onu oyladığınızdan emin olun !!
@Grimy sayesinde -1 bayt.

Karakter listesi olarak çıktılar.

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

Açıklama:

   4¡ˆ¶ü]₁η₃•          # Push compressed integer 82767635194143615015
              ₃в        # Converted to base-95 as list: [1,36,30,85,0,67,66,8,49,7,0]
                IÇ      # Push the input and convert each character to its unicode value
                  è     # Index each into the list we created
                   ā    # Push an integer list in the range [0, length] 
                        # (without popping the list itself)
                    -   # Subtract it from the previous list
žQ                      # Push builtin with all printable ASCII characters,
  ¦                     # and remove the leading space
                     è  # Index the values of the list into the ASCII characters
                        # (after which the result is output implicitly)

Bu 05AB1E madenin ucu bakın (bölüm ne kadar büyük tamsayılar sıkıştırmak için? Ve kompres tamsayı listelerine nasıl? ) Anlamak için •4¡ˆ¶ü]₁η₃•ise 82767635194143615015ve •4¡ˆ¶ü]₁η₃•₃вolup [1,36,30,85,0,67,66,8,49,7,0].


•1ÃQWý₂Ýδ9•86в->•4¡ˆ¶ü]₁η₃•₃в
Grimmy

@Grimy Thanks :)
Kevin Cruijssen

2

Perl 5 ( -p), 53 , 51 bayt

kullanılarak, 2 bayt tasarruf de{#0ABTyerine '(>DQbcu, böylece 61artık ihtiyaç

y;*jpovi</;de{#0ABT;;s/./chr 33+(-"@-"+ord$&)%94/ge

TIO

ilk cevap

y;*jpovi</;'(>DQbcu;;s/./chr 33+(61-"@-"+ord$&)%94/ge

TIO


2

Japt , 24 23 bayt

Port of Nick's Jelly çözümü

;£EÅgYn" #T BA0 "cXc

Dene

;£EÅgYn"..."cXc     :Implicit input of string
 £                  :Map each character X at 0-based index Y
; E                 :ASCII
   Å                :Slice of the first character (space)
    g               :Get character at index
     Y              :  Increment Y
      n             :  Subtract from
       "..."        :    Literal string (Codepoints: 32,35,29,84,32,66,65,7,48,6,32)
            c       :    Codepoint at index
             Xc     :      Codepoint of X

1

Retina 0.8.2 , 50 bayt

T`*j\p\ovi</`'(>DQbcu
.
$.`$* $&¶
+T`!p`~_p` .¶
¶

Çevrimiçi deneyin! Bağlantı, test senaryolarını içerir. Açıklama:

T`*j\p\ovi</`'(>DQbcu

Harf çevirisi soruda açıklandığı gibi yapın. p(aşağıda açıklanmıştır) ve alıntı yapmak için oözel bir anlamı vardır, Tbu yüzden tırnak içine alınmaları gerekir.

.
$.`$* $&¶

Her karakteri, kendi dizininde, dizinine göre bir dizi boşluk, yani program sayacının ne olacağı gibi listeleyin.

+T`!p`~_p` .¶

Her satırdaki son karakteri, boşlukların tümü silinene kadar her seferinde önceki alanı silerek tekrar tekrar döngüsel olarak azaltın. pYazdırılabilir ASCII için standları yani -~, ancak istediğimiz !eşlemek için ~ilk çevirilir bu nedenle, sonra _maçında boşluk neden kalan karakterler birer birer karakter kodu çevirilir olsun ederken, silinecek.

Tüm karakterleri tekrar birleştirin.


1

Kömür , 23 bayt

⭆S§Φγμ⁻℅§ #{T BAe0d ℅ικ

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. @ Arnauld'un JavaScript yanıtı portu. Açıklama:

 S                      Input string
⭆                       Map over characters and join
                     ι  Current character
                    ℅   ASCII code
        §               Cyclically indexed into
          #{T BAe0d     Literal string ` #{T BAe0d `
       ℅                ASCII code
      ⁻                 Subtract
                      κ Current index
  §                     Cyclically indexed into
    γ                   Printable ASCII
   Φ                    Filtered on
     μ                  Inner index (i.e. skip initial space)
                        Implicitly print


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.