Sayıları 0'a Böl


16

Hepimize hayatımızın bir noktasında 0'a bölünmenin imkansız olduğu söylendi. Ve çoğunlukla, bu ifade doğrudur. Ama ne olur idi yasak işlemi gerçekleştirmek için bir yol? En yeni yaratıma hoş geldiniz:b -sayıları.

bİlgili ana pronumeral (matematiksel olarak imkansız değildir bir ifade temsil eder: -Sayılar hayali sayılar gibi biraz vardır itemsil 1 ). Bu durumdabifadesini 1 temsil ettiği söylenecektir.10 . Buradan,x'inne olduğunu belirlemek kolaydır.x0 eşittir:

x0=x110=xb

Görev

0'a bölünmeyi içeren bir ifade verildiğinde, b cinsinden basitleştirilmiş değeri çıktılayın . Girdinin n/0n'nin herhangi bir rasyonel sayı veya herhangi bir sayı olduğu biçiminde olacağını unutmayın.bGirdinin, ondalık biçimde . Baştaki 0'lar ve sondaki 0'lar dahil edilmeyecektir.

Örnek Giriş

4/0
1/0
0/0
80/0
-8/0
1.5/0
2.03/0
-1/0
-3.14/0
b/0
3b/0
-b/0
121/0

Örnek Çıktı

4b
b
0
80b
-8b
1.5b
2.03b
-b
-3.14b
b
3b
-b
121b

Puan

Bu kod golf, çok az bayt kazanır. Standart boşluklar yasaktır.

Liderler

İşte hem düzenli bir skor tablosu hem de kazananları dile göre gözden geçirmek için bir Yığın Parçacığı.

Yanıtınızın göründüğünden emin olmak için lütfen aşağıdaki Markdown şablonunu kullanarak yanıtınızı bir başlıkla başlatın:

# Language Name, N bytes

Ngönderiminizin büyüklüğü nerede . Puanınızı artırmak varsa, olabilir onları içinden vurarak, başlığa eski hesapları tutmak. Örneğin:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Başlığınıza birden fazla sayı eklemek istiyorsanız (örneğin, puanınız iki dosyanın toplamı olduğu veya yorumlayıcı bayrak cezalarını ayrı olarak listelemek istediğiniz için), gerçek puanın başlıktaki son sayı olduğundan emin olun :

# Perl, 43 + 2 (-p flag) = 45 bytes

Dil adını, daha sonra skor tablosu snippet'inde görünecek bir bağlantı da yapabilirsiniz:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


7
Yanlış bir şey yaptığımdan şüpheleniyorum, ama eğer b/0 = bo zaman iki parçayı da bo zaman bölersem 1/0 = 1. cBöyle bölmek için numaralara ihtiyacım var mı?
zamirim monicareinstate

4
@Erik bu şekilde, b/b = 0normalde (ve tüm çeşitli aksiyomlardan kolayca kanıtlandığından eminim) 1 olması bekleniyor (aksi takdirde b'nin çarpımsal tersi, çarpımsal tersi gibi görünmüyor). Eminim ekleyerek b=1/0veya benzer bir şeyle sıfıra bölünmeye karşı boşluk bırakamazsınız .
zamirim monicareinstate

30
Sıfıra bölmenin tanımsız olmasının bir nedeni var ... . Sadece tüm örnekler (0 üçte hariç) basitleştirmek mümkün olmalıdır Yanibb=1b=11b=33b=3130=30=310=3bb
Çoğunlukla Zararsız

8
3. örnekte çıktı 0byerine değil 0mi? İki ifade eşdeğer olsaydı, sorunun önceliği olmazdı
trichoplax

4
Önerilen test örneği:3.1b/0
jimmy23013

Yanıtlar:


19

Bozulmamış Malbolge (20-trit dönüş varyantı), 3,62e6 bayt

Bu cevabın boyutu maksimum postalanabilir program boyutunu (eh) aşıyor, bu nedenle kod GitHub veri havuzumda bulunuyor (not: Kodu CTRL + A ve CTRL + C kullanarak kopyalamayın, sağ tıklayın ve "Hedef öğeyi farklı kaydet" i tıklayın. .. ").

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, ama ne yazık ki kullanamıyorum (sınırlamalar).

Bulabildiğim en iyi şey, çok iyi performans gösteren ve hemen (neredeyse) hesaplayan sabit 20-trit dönüş genişliği varyantıdır .

Tercümanı biraz daha hızlı hale getirmek için Matthias Lutter'ın Malbolge Shackled tercümanındaki tüm kontrolleri kaldırdım.

#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!


6
Umarım hepsini yazmamışsınızdır.
connectyourcharger

5
Programınızı açtığımda Chrome, programı
Lehçe'den

@Tharwen bir bakışta, Polonyalı mı yoksa sadece Malbolge mu olduğunu söylemek zor. Ne yazık ki benim dilim öğrenmek için yeryüzünde cehennem.
Krzysztof Szewczyk

7

PHP , 65 64 61 58 bayt

-1 bayt (boş dize) byerine kullanılır ''. "B" ler kırpıldığı için, bu özel durumda boş bir dize ile aynı olacaktır.

Girdinin ilk kısmını almak substryerine kullanarak -3 bayt explode.

-3 byte ile daha iyi yöntemler kullanarak tespit 1ve -1.

<?=($n=substr($argn,0,-2))?trim($n+1?$n-1?$n:b:'-',b).b:0;

Çevrimiçi deneyin!

Testler: Çevrimiçi deneyin!

"/" (Biz diyoruz $n) öncesi girdinin ilk kısmı 0 ise, 0 yazdırır.

Else $n, sonunda kesilmiş herhangi bir "b" ve -1 ve 1 özel durumları ile baskı yapar, böylece "1" basamağı yazdırılmaz. Ve sonunda tek bir "b" ekler. Kırpma kısmı, sonunda "3bb" gibi bir çift "b" almadığımızdan emin olmaktır.


çok iyi yapmışsın!
Lyxal

Değiştirme $n==-1 ile$n>0(-2 bayt) işe yarıyor gibi görünüyor. Bunu deneyebilirsin.
Ismael Miguel

@IsmaelMiguel, demek istiyorsan, çalışmıyor $n<0 , o da işe yaramaz, çünkü bizim gibi girdilerimiz var-8/0 .
Gece2

@IsmaelMiguel, ama bana yerini bir fikir verdi $n==-1?'-':$nile $n+1?$n:'-'2 bayt kaydetmek için!
Gece2

1
: / Test ettiğimde işe yaramış gibiydi. ama başka bir yolla bulduğunuz iyi bir şey.
Ismael Miguel


4

Jöle , 18 bayt

Erik'in çaldığı ṾṖ$İƑ¡ için (aksi takdirde 19 tane de olurdu) ...

ṖṖv0ḢṾṖ$İƑ¡,Ạ¡”boḢ

Sonucu basan tam bir program.

Çevrimiçi deneyin! Veya bakın test takımına bakın .

Nasıl?

ṖṖv0ḢṾṖ$İƑ¡,Ạ¡”boḢ - Main Link: list of characters S
Ṗ                  - discard right-most (of S)
 Ṗ                 - discard right-most
   0               - literal zero
  v                - evaluate as Jelly code with right argument (0)
                   - ... b is covert-to-base, so "nb0" gives [n]
    Ḣ              - head ([n]->n or n->n)
          ¡        - repeat...
         Ƒ         - ...# of times: is invariant under:
        İ          -   reciprocation (n->1/n)
       $           - ...action: last two links as a monad:
     Ṿ             -   un-evaluate (-1->"-1" or 1->"1")
      Ṗ            -   discard right-most ("-1"->"-" or "1"->"")
             ¡     - repeat...
            Ạ      - ...# of times: all?
           ,  ”b   - ...action: pair with a 'b' character
                o  - logical OR with:
                 Ḣ -   head (S)  (i.e. if we end with 0 use the 1st character of the input)
                   - implicit print

1
Ahhh ve ben kötüye kullanabileceğim yolları düşünüyordum v...: D
Outgolfer Erik

4

Perl 6 , 32 bayt

{~m/^0/||S/[(\-|^)1|b]?\/0/$0b/}

Çevrimiçi deneyin!

Biri regexes, biri girişin olup olmadığını kontrol etmek için 0/0, diğeri de sondaki /0ile sadece değiştirmek b(ve eski b,1 ve / veya-1 )

Açıklama (eski)

{                          }  # Anonymous codeblock
 ~m/^0/     # Return 0 if the input starts with 0
       ||   # Otherwise
         S/             / /  # Substitute
                     \/0       # The /0
          (        )?          # Optionally starting with
           <wb>1               # 1 or -1
                |b             # Or b
                         b   # With just b

3

Retina , 28 24 bayt

b?/0
b
^0b
0
(^|-)1b
$1b

Çevrimiçi deneyin!

İlk olarak Retina'yı kullanmayı deneyin, bu yüzden muhtemelen golf için önemli bir yer var.



Ne için avcılık sonra \byapar (ben o , biraz bu basılamaz geri silme karakteri kısaltılmış edilemez bulmak için hayal kırıklığına uğradım regex ile deneyimsiz). Her neyse, teşekkürler
İlgisiz String

1
@UnrelatedString elbette backspace'a kısaltılamaz, sonuçta, \bnormal dizelerde
yalnızca

2

Python 3 , 68 bayt

import re
print(re.sub('^0b$','0',re.sub(r'(^1)?b?/0','b',input())))

Çevrimiçi deneyin!


Güzel çözüm! Ancak import rebayt sayısını 64'e çıkarır.
movatica

1
@movatica iyi bir nokta, burada yeni ithalat beyanı dahil edildi farkında değildi (tabii ki öyle olsa da). Düzenlenen.
Kazim

Hoşgeldiniz! :) Yine de daha kısa lambda sürümünü tutabilirsiniz! Tam bir program olması gerekmez. Ve ithalat ifadesi lambda tanımından sonra yerleştirilebilir, böylece 64 bayt mümkündür !
movatica

1
@movatica ah, güzel! İthalat ve lambda ile çalışmasını sağlayacak bir yol bulamadım. Teşekkür ederim
Kazim

1

Fıçı , 18B

Tüm kredi Jono 2906'ya aittir.

__:b=;[b]^:\1=[_]^

açıklama

__                 # Take implicit input and remove the "trash" (/0).
  :b=              # Is the last character equal to b?
     ;             # Negate(decrement) this value.
      [b]          # If the last character is not b, append b.
         ^         # Reverse the stack.
          :\1=     # Is the first character equal to 1?
              [_]  # If so, reduce the value.
                 ^ # Reverse the stack back and implicit output.

TIO!



1

JavaScript (ES6), 45 bayt

s=>+(n=s.split`/`[0])?[n*n-1?n:'-'[~n]]+'b':n

Çevrimiçi deneyin!

Yorumlananlar

s =>                  // s = input: "numerator/0"
  +(                  //
    n = s.split`/`[0] // n = numerator, as a string
  ) ?                 // if n coerced to a Number is neither equal to 0 nor NaN:
    [ n * n - 1 ?     //   if abs(n) is not equal to 1:
        n             //     append the numerator
      :               //   else:
        '-'[~n]       //     append '-' if n = -1, or an empty string otherwise
    ] + 'b'           //   append 'b'
  :                   // else:
    n                 //   just output the numerator because it's either "0" or
                      //   an expression that already contains 'b'

1

Cı, 209 203 137 bayt

Tavan kedisi sayesinde -66 bayt

char a[9];main(f){gets(a);f=strlen(a)-3;a[f+1]=0;printf((*a==55&a[1]==49&f==1?a[1]=98:*a==49&!f?*a=98:a[f]==98|*a==48&!f)?"%s":"%sb",a);}

TIO


-0/0 koymak -0b verir, ancak hiçbir zaman örnek girdi veya test senaryolarında değildi, bu yüzden doğru.
girobuz

1

naz , 64 bayt

6a8m1s2x1v2m4a2x2v1x1f1r3x1v2e3x2v3e1o1f0x1x2f2m4a1o0x1x3f1o0x1f

Açıklama ( 0xkomutlar kaldırıldığında)

6a8m1s2x1v             # Set variable 1 equal to 47 ("/")
2m4a2x2v               # Set variable 2 equal to 98 ("b")
1x1f                   # Function 1
    1r                 # Read a byte of input
      3x1v2e           # Jump to function 2 if it equals variable 1
            3x2v3e     # Jump to function 3 if it equals variable 2
                  1o1f # Otherwise, output it and jump back to the start of the function
1x2f2m4a1o             # Function 2
                       # Set the register equal to 98 and output once
1x3f1o                 # Function 3
                       # Output once
1f                     # Call function 1

0

Brainfuck, 25 bayt

>,[>,]<[-<+>]<+++[<]>[.>]

açıklama

>,[>,]        read from stdin
<[-<+>]<+++   add last two cells and add three ( ascii('/') + ascii('0') + 3 = ascii('b')
[<]>          move pointer to first char to output
[.>]          output until cell w/ value 0

1
b/0beklenen b, var bb; 0/0beklenen 0, var 0b; -1/0beklenen -b, var -1b.

Evet, temelde bu sadece değiştirir /0için bve dikkate vakaların herhangi almaz 0b, 1b, -1bya da zaten bir içerdiğini herhangi girdilerb
Jo Kral
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.