Divida números por 0

16

Todos nós já fomos informados em algum momento de nossas vidas que dividir por 0 é impossível. E, na maior parte, essa afirmação é verdadeira. Mas e se não era uma maneira de realizar a operação proibido? Bem-vindo à minha mais nova criação: b-numbers.

b-números são um pouco parecidos com números imaginários: o principal pronumeral envolvido representa uma expressão que não é matematicamente impossível ( irepresenta -1 ). Nesse caso, será dito quebrepresenta a expressão10 0 . A partir daqui, é fácil determinar o quex0 0 seria igual:

x0 0=x110 0=xb

A tarefa

Dada uma expressão envolvendo uma divisão por 0, produza o valor simplificado em termos de . Observe que a entrada estará na forma de onde n é qualquer número racional ou qualquer -número na forma decimal. 0s iniciais e 0s finais não serão incluídos.bn/0b

Exemplo de entrada

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

Saída de exemplo

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

Ponto

Isso é código de golfe, e o menor número de bytes vence. As brechas padrão são proibidas.

Classificação

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

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

Você também pode transformar o nome do idioma em um link que será exibido no snippet do placar de líderes:

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

Jono 2906
fonte
7
Eu suspeito que estou fazendo algo errado, mas, se estiver b/0 = b, se eu dividir as duas partes até bentão 1/0 = 1. Preciso de c-números para dividir assim?
meu pronome é monicareinstate 31/08/19
4
@ Erik dessa maneira, b/b = 0quando normalmente (e tenho certeza de que é facilmente comprovado por todos os vários axiomas) esperado 1 (caso contrário, o inverso multiplicativo de b parece não ser o inverso multiplicativo). Tenho certeza que você simplesmente não pode brigar contra a divisão por zero adicionando b=1/0ou algo parecido.
meu pronome é monicareinstate 31/08/19
30
Existe uma razão pela qual a divisão por zero é indefinida ... . Então você deve ser capaz de simplificar todos os exemplos (exceto o terceiro de 0) para apenasbb=1b=11b=33b=3130 0=30 0=310 0=3bb
na maior parte inofensiva
8
O terceiro exemplo não deveria ter saída 0be não 0? Se as duas expressões são equivalentes então a questão não teria nenhuma premissa
Trichoplax
4
Caso de teste sugerido:3.1b/0
jimmy23013 01/09/19

Respostas:

19

Malbolge Unshackled (variante de rotação de 20 trit), 3,62e6 bytes

O tamanho desta resposta excede o tamanho máximo do programa postável (eh); portanto, o código está localizado no meu repositório GitHub (nota: não copie o código usando CTRL + A e CTRL + C, basta clicar com o botão direito e clicar em "Salvar elemento de destino como. .. ").

Como executar isso?

Isso pode ser uma parte complicada, porque o intérprete ingênuo de Haskell levará anos e mais anos para executar isso. O TIO possui um intérprete decente do Malbogle Unshackled, mas, infelizmente, não poderei usá-lo (limitações).

O melhor que eu pude encontrar é a variante fixa de largura de rotação de 20 trit, que executa muito bem, calculando (praticamente) instantaneamente .

Para tornar o intérprete um pouco mais rápido, removi todas as verificações do intérprete Malbolge Unshackled de Matthias Lutter.

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

Está funcionando!

Está funcionando!

Krzysztof Szewczyk
fonte
6
Espero que você não tenha digitado tudo isso.
connectyourcharger
5
Quando abri o seu programa, o Chrome tentou traduzi-lo do polonês
Tharwen 03/09/19
@Tharwen de relance, é difícil dizer se é polonês ou apenas Malbolge. Infelizmente, minha língua é um inferno na terra para aprender.
Krzysztof Szewczyk
7

PHP , 65 64 61 58 bytes

-1 byte usando um em bvez de ''(string vazia). Como "b" s são cortados, será o mesmo que uma string vazia neste caso específico.

-3 bytes usando em substrvez de explodepara obter a primeira parte da entrada.

-3 bytes usando métodos melhores para detectar 1e -1.

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

Experimente online!

Testes: Experimente online!

Se a primeira parte da entrada antes de "/" (como chamamos $n) for 0, imprime 0.

$nCaso contrário, imprime- se com qualquer "b" no final aparado e casos especiais de -1 e 1 manipulados, para que o dígito "1" não seja impresso. E no final acrescenta um único "b". A parte de corte é garantir que não recebamos um "b" duplo no final, como "3bb".

Night2
fonte
muito bem feito!
Jono 2906
Substituir $n==-1por $n>0(-2 bytes) parece funcionar. Você poderia tentar isso.
Ismael Miguel
@IsmaelMiguel, que não está funcionando, se você quis dizer $n<0, também não funcionará, já que temos entradas como -8/0.
Night2
@IsmaelMiguel, mas você me deu uma idéia, substituída $n==-1?'-':$npor $n+1?$n:'-'para economizar 2 bytes!
night2
1
: / Quando eu testei, parecia funcionar. mas bem, coisa boa que você encontrou de outra maneira.
Ismael Miguel
4

Gelatina , 18 bytes

Acabei roubando o Erik ṾṖ$İƑ¡ para este (caso contrário, eu também teria 19) ...

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

Um programa completo que imprime o resultado.

Experimente online! Ou veja a suíte de testes .

Quão?

ṖṖ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
Jonathan Allan
fonte
1
Ahhh, e eu estava pensando em maneiras de abusar v...: D
Erik the Outgolfer
4

Perl 6 , 32 bytes

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

Experimente online!

Um par de expressões regulares, um para verificar se a entrada for 0/0, e o outro para substituir o arrasto /0com apenas b(e para remover a idade b, 1e / ou -1)

Explicação (antiga)

{                          }  # 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
Brincadeira
fonte
3

Retina , 28 24 bytes

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

Experimente online!

Primeiro tente usar o Retina, para que haja provavelmente um espaço considerável para jogar golfe.

String não relacionada
fonte
2
18 bytes: Experimente online!
precisa saber é o seguinte
Depois de caça para o que \bfaz (eu sou que inexperientes com regex), eu estava um pouco desapontado ao descobrir que ele não pode ser encurtado para o personagem backspace impublicável. De qualquer forma, obrigado
String não relacionada
1
@UnrelatedString é claro que não pode ser encurtado para backspace, afinal de contas, \bé apenas uma representação ASCII do caractere backspace em strings normais: P
somente ASCII
2

Python 3 , 68 bytes

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

Experimente online!

Kazim
fonte
Ótima solução! Mas import resurge a bytecount a 64.
movatica
1
@movatica bom ponto, novo aqui, então não percebi declaração de importação foi incluída (embora é claro que é). Editado.
Kazim
Bem-vinda! :) Você ainda pode manter a versão lambda mais curta! Não precisa ser um programa completo. E a instrução de importação pode ser colocada após a definição lambda, para que sejam possíveis 64 bytes !
movatica 2/09/19
1
@movatica ah, que bom! Não encontrei uma maneira de fazê-lo funcionar com importação e lambda. Obrigado
Kazim
1

Barril , 18B

Todo o crédito é para Jono 2906.

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

Explicação

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

uma'_'
fonte
1

JavaScript (ES6), 45 bytes

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

Experimente online!

Comentado

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'
Arnauld
fonte
1

C, 209 203137 bytes

-66 bytes graças ao ceilingcat

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

girobuz
fonte
A inserção de -0/0 fornece -0b, mas nunca foi nos casos de entrada ou teste de exemplo, portanto está correto.
girobuz 4/09/19
0

Brainfuck, 25 bytes

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

Explicação

>,[>,]        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
Michael
fonte
1
b/0esperado b, tenho bb; 0/0esperado 0, tenho 0b; -1/0esperado -b, entendi -1b.
a'_ '03
Sim, basicamente isso só substitui o /0para be não leva em consideração qualquer dos casos, para 0b, 1b, -1bou quaisquer entradas que já contêm umab
Jo King