Maneira correta de adicionar números para obter muitos 8

16

Inspirado por essa pergunta, que foi inspirada por essa , escreva um programa que use dois números inteiros e os adicione de uma maneira única, executando uma operação OR nos segmentos usados ​​para exibi-los em um display de 7 segmentos. Para referência, os dígitos são representados da seguinte maneira:

 _        _   _         _    _   _    _    _
| |   |   _|  _|  |_|  |_   |_    |  |_|  |_|
|_|   |  |_   _|    |   _|  |_|   |  |_|   _| 

Observe que o 1 usa os dois segmentos à direita, não à esquerda. Existem dois caracteres especiais que podem ser produzidos dessa maneira e não são números. Veja a tabela de adição abaixo:

  | 0 1 2 3 4 5 6 7 8 9
--+--------------------
0 | 0 0 8 8 8 8 8 0 8 8
1 | 0 1 a 3 4 9 8 7 8 9
2 | 8 a 2 a 8 8 8 a 8 8
3 | 8 3 a 3 9 9 8 3 8 9
4 | 8 4 8 9 4 9 8 Q 8 9
5 | 8 9 8 9 9 5 6 9 8 9
6 | 8 8 8 8 8 6 6 8 8 8
7 | 0 7 a 3 Q 9 8 7 8 9
8 | 8 8 8 8 8 8 8 8 8 8
9 | 8 9 8 9 9 9 8 9 8 9

Observações úteis:

  • Qualquer dígito mais ele mesmo se iguala
  • 8 mais qualquer dígito é igual a 8
  • 2 mais 1, 3 ou 7 é igual à letra 'a' (deve estar em minúscula)
  • 4 mais 7 é igual a 'q' ou 'Q', sua escolha
  • Os números devem estar alinhados à direita, para que os dígitos sejam adicionados da direita para a esquerda. Se um número tiver mais dígitos que o outro, os dígitos extras no início deverão permanecer inalterados. Não há 0's iniciais, a menos que o número seja exatamente 0.
  • Todos os números serão 0 ou mais. Você não precisa manipular um sinal de '-'. (Principalmente porque não há um ajuste adequado para a soma de um '-' e um '1' ou '7'.)

Seu programa deve aceitar 2 números inteiros em qualquer formato que você escolher e gerar uma string contendo sua "soma" quando calculada dessa maneira. Isso é código-golfe, então seu programa deve ser o menor possível.

Exemplos:

  • Entrada: 12345, 123. Saída: 12389
  • Entrada: 88888, 42. Saída: 88888
  • Entrada: 0, 23. Saída: 28
  • Entrada: 120, 240. Saída: a80
  • Entrada: 270, 42. Saída: 2Q8 (ou 2q8)
  • Entrada: 1234567890, 1234567890. Saída: 1234567890
Darrel Hoffman
fonte
4
Desafio interessante, mas isso pode usar alguns casos de teste para que as pessoas possam validar suas respostas.
AdmBorkBork
3
Não deveria Qser minúsculo? A forma real parece qmais do que umaQ
Luis Mendo
Os números inteiros de entrada serão de um dígito, número limitado de dígitos ou ilimitados?
Digital Trauma
1
@LuisMendo - Suponho que poderia ser de qualquer maneira. Deixarei isso a seu critério. O adefinitivamente deve ser menor que caso, já que Aparece completamente diferente.
Darrel Hoffman
2
@ Adám - Sim, eu pensei sobre isso, mas percebi que nem todo mundo tem acesso a caracteres Unicode em seus idiomas de golfe, por isso seria injusto esperar que eles lidem com isso.
Darrel Hoffman

Respostas:

7

Bash + utilitários comuns do Linux, 80

s=~0my3[_p^?{}s
h()(tr 0-9 $s<<<$1|xxd -p)
dc -e$[0x`h $1`|0x`h $2`]P|tr $s 0-9aQ

Observe que a ^?fonte deve ser substituída por um caractere ASCII 0x7f.

A string sé cada dígito de 7 segmentos 0-9, a, Qcodificado com cada segmento correspondente a um bit de um caractere ASCII.

A h()função translitera o número de entrada de decimal para a codificação especificada por se gera o resultado como uma sequência hexadecimal bruta.

As duas seqüências de caracteres hexadecimais brutas resultantes são OReditadas em conjunto usando aritmética bash regular e, em seguida, são geradas pelo comando dcs Pcomo um bytestream. Este bytestream é então transliterado de volta para decimal + a + Q e saída.

Observe também que, ao usar a <<<construção bash herestring na função, h()uma nova linha é anexada implicitamente à string redirecionada. Isso não importa - é simplesmente traduzido 0x0ano final de cada sequência hexadecimal; quando os dois números hexadecimais são OReditados juntos, o resultado ainda está 0x0ano último caractere que não é transliterado e, portanto, simplesmente se converte em uma nova linha que é produzida após o resultado.

Saída de teste:

$ for testcase in \
> "12345 123" \
> "88888 42" \
> "0 23" \
> "1234 56789" \
> "4 7"; do 
> ./7segadd.sh $testcase
> done
12389
88888
28
58a89
Q
$ 
Trauma Digital
fonte
1
Vou seguir em frente e premiar isso, já que ninguém parece mais tentar este.
Darrel Hoffman
Obrigado Darrel - Foi um desafio divertido e interessante. Se você quiser mais respostas, considere colocar uma recompensa.
Digital Trauma
Não, eu não tenho representante suficiente neste site para gastar tudo em recompensas. (Eu não posso nem testar este porque não estou executando o Linux, estou apenas dando à comunidade o benefício da dúvida.) Eu meio que juntei tudo isso por um capricho, com base em outra pergunta.
Darrel Hoffman
3

Python 2, 155 bytes

def f(a,b):exec"a=[ord('?(u|j^_,♥~'[int(c)])for c in a];a=max(len(b)-len(a),0)*[0]+a;a,b=b,a;"*2;print`['214567q3a980'[(c|d)%13]for c,d in zip(a,b)]`[2::5]

Substitua por um DELcaractere (0x7F).

Chamando f("12345", "123")impressões 12389.

Lynn
fonte
Existem três conjuntos de valores para os quais esse %13truque funciona. Obviamente, você optou pelo conjunto que não tinha caracteres abaixo de 40, mas na minha tradução em JavaScript eu escolhi o conjunto mais curto. O terceiro conjunto é o mais longo em JavaScript, teria sido 111,5,118,117,29,121,123,37,127,125.
Neil
2

JavaScript (ES6), 158 144 bytes

f=(s,t)=>t[s.length]?f(t,s):s[t.length]?f(s,' '+t):s.replace(/./g,(c,i)=>"540q9361278a"[(a[c]|a[t[i]])%13],a=[119,20,47,31,92,91,123,22,127,95])

Economizou 14 bytes roubando descaradamente o %13truque de @ Lynn .

f=(s,t)=>t[s.length]?f(t,s):s[t.length]?f(s,' '+t):s.replace(/./g,(c,i)=>"540q9361278a"[(a[c]|a[t[i]])%13],a=[119,20,47,31,92,91,123,22,127,95])
;o.textContent=[...s="0123456789"].map(c=>f(c.repeat(10),s)).join`
`;
<pre id=o></pre>

Neil
fonte
1

Java, 170 bytes

Isso é terrivelmente longo ... mas, de qualquer forma, é Java.

String A(int a,int b){String c="|HgmY=?h}oy",r="";for(;a>0|b>0;a/=10,b/=10)r="0123456789aq".charAt(c.indexOf((a>0?c.charAt(a%10):0)|(b>0?c.charAt(b%10):0)))+r;return r;}

Programa completo, com código não bloqueado

public class Q80716 {
    String A(int a,int b){String c="|HgmY=?h}oy",r="";for(;a>0|b>0;a/=10,b/=10)r="0123456789aq".charAt(c.indexOf((a>0?c.charAt(a%10):0)|(b>0?c.charAt(b%10):0)))+r;return r;}
    String Add(int a,int b){
        String c = "|HgmY=?h}oy", d = "0123456789aq";
        String r = "";
        for(;a>0|b>0;a/=10,b/=10){
            r = d.charAt(c.indexOf((a>0?c.charAt(a%10):0)|(b>0?c.charAt(b%10):0))) + r;
        }
        return r;
    }
    public static void main(String[]args){
        int[][] testcases = new int[][]{
            {12345,123},
            {88888,42},
            {0,23},
            {120,240},
            {270,42},
            {1234567890,1234567890}
        };
        for(int i=0;i<testcases.length;i++){
            System.out.println(new Q80716().Add(testcases[i][0],testcases[i][1]));
            System.out.println(new Q80716().A(testcases[i][0],testcases[i][1]));
        }
    }
}

Todas as saídas (todas duplicadas uma vez)

12389
88888
23
a80
2q8
1234567890
Freira Furada
fonte
Eu prometo que não vou usar golflangs para resolver este problema (provavelmente custaria não mais de 50 bytes)
Leaky Nun
Eu nunca disse que as pessoas não podiam usar idiomas de golfe para isso - estou sinceramente surpreso que ninguém ainda o tenha feito. De qualquer forma, mesmo sem isso você provavelmente poderia salvar alguns bytes usando um lambda Java 8?
Darrel Hoffman