Правильный способ добавить цифры, чтобы получить много 8

16

Вдохновленный этим вопросом , который далее вдохновил этот , написать программу , которая принимает два целых числа и складывает их уникальным способом, путем выполнения операции ИЛИ на сегментах , используемых для их отображения на дисплее 7-сегмента. Для справки, цифры представлены следующим образом:

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

Обратите внимание, что 1 использует два сегмента справа, а не слева. Таким способом можно создать два специальных символа, которые не являются числами. Смотрите таблицу дополнений ниже:

  | 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

Полезные наблюдения:

  • Любая цифра плюс сама по себе равна
  • 8 плюс любая цифра равна 8
  • 2 плюс 1, 3 или 7 равно букве «а» (должно быть в нижнем регистре)
  • 4 плюс 7 равняется 'q' или 'Q', на ваш выбор
  • Числа должны быть выровнены по правому краю, поэтому цифры следует добавлять справа налево. Если одно число имеет больше цифр, чем другое, дополнительные цифры в начале должны быть неизменными. Нет начальных 0, если только число не равно 0.
  • Все числа будут 0 или больше. Вам не нужно обрабатывать знак «-». (Главным образом потому, что нет подходящей суммы на сумму «-» и «1» или «7».)

Ваша программа должна принимать 2 целых числа в любом формате, который вы выберете, и выводить строку, содержащую их «сумму» при расчете таким образом. Это код-гольф, поэтому ваша программа должна быть как можно меньше.

Примеры:

  • Вход: 12345, 123. Выход: 12389
  • Вход: 88888, 42. Выход: 88888
  • Вход: 0, 23. Выход: 28
  • Вход: 120, 240. Выход: a80
  • Вход: 270, 42. Выход: 2Q8 (или 2Q8)
  • Вход: 1234567890, 1234567890. Выход: 1234567890
Даррел Хоффман
источник
4
Интересная задача, но для этого можно использовать некоторые контрольные примеры, чтобы люди могли проверить свои ответы.
AdmBorkBork
3
Не должно Qбыть в нижнем регистре? Фактические формы , выглядит как , qа неQ
Луис Mendo
Будут ли входные целые числа однозначными, ограниченным числом или неограниченным?
Цифровая травма
1
@LuisMendo - я полагаю, это может пойти в любую сторону Я оставлю это на ваше усмотрение. Тем aне менее, он должен быть в нижнем регистре, так как Aвыглядит совершенно иначе.
Даррел Хоффман
2
@ Adám - Да, я думал об этом, но подумал, что не у всех есть доступ к персонажам Юникода на их любимых языках игры в гольф, поэтому было бы несправедливо ожидать, что они справятся с этим.
Даррел Хоффман

Ответы:

7

Утилиты Bash + Common 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

Обратите внимание, что ^?источник должен быть заменен символом ASCII 0x7f.

Строка s- это каждая 7-сегментная цифра, 0-9, a, Qзакодированная с каждым сегментом, соответствующим биту ASCII-символа.

h()Функция транслитерирует номер входа десятичных чисел в кодировке , указанной s, затем выводит результат в качестве исходного шестнадцатеричной строки.

Две результирующие необработанные шестнадцатеричные строки редактируются ORвместе с использованием обычной арифметики bash, а затем выводятся dcс помощью Pкоманды в качестве байтового потока. Затем этот поток байтов транслитерируется обратно в десятичное число + a + Q и выводится.

Также обратите внимание, что при использовании <<<конструкции bash herestring в функции новая h()строка неявно добавляется к перенаправленной строке. Это не имеет значения - оно просто переводится 0x0aв конец каждой шестнадцатеричной строки; когда два шестнадцатеричных числа ORобъединены, результат остается 0x0aв последнем символе, который не транслитерируется и, таким образом, просто переводится обратно на новую строку, которая выводится после результата.

Тестовый вывод:

$ for testcase in \
> "12345 123" \
> "88888 42" \
> "0 23" \
> "1234 56789" \
> "4 7"; do 
> ./7segadd.sh $testcase
> done
12389
88888
28
58a89
Q
$ 
Цифровая травма
источник
1
Я пойду вперед и награжу это, так как никто, кажется, больше не пробует это.
Даррел Хоффман
Спасибо, Даррел. Это было весело, интересно. Если вы хотите получить больше ответов, вы можете подумать о том, чтобы наградить их.
Цифровая травма
Нет, у меня недостаточно представителей на этом сайте, чтобы тратить все на награды. (Я даже не могу протестировать этот, так как я не работаю с Linux, я просто даю сообществу преимущество сомнения.) Я просто отчасти отбросил все это по прихоти, основываясь на другом вопросе, так или иначе.
Даррел Хоффман
3

Python 2, 155 байт

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]

Заменить сDEL характером (0x7F).

Вызов f("12345", "123")принты 12389.

Линн
источник
Есть три набора значений, для которых этот %13трюк работает. Очевидно, вы выбрали набор, в котором не было символов ниже 40, но для перевода на JavaScript я выбрал самый короткий набор. Третий набор самый длинный в JavaScript, это было бы 111,5,118,117,29,121,123,37,127,125.
Нил
2

JavaScript (ES6), 158 144 байта

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])

Спас 14 байтов, бесстыдно украдя %13трюк Линн .

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>

Нил
источник
1

Java, 170 байт

Это ужасно долго ... но это все равно 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;}

Полная программа с негольфированным кодом

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]));
        }
    }
}

Весь вывод (все дублируются один раз)

12389
88888
23
a80
2q8
1234567890
Пропитанная монахиня
источник
Я обещаю, что не буду использовать Golflangs для решения этой проблемы (вероятно, это будет стоить не более 50 байтов)
Leaky Nun
Я никогда не говорил, что люди не могут использовать для этого языки гольфа - я, честно говоря, удивлен, что никто этого еще не сделал. В любом случае, даже без этого вы могли бы сэкономить несколько байтов, используя лямбду Java 8?
Даррел Хоффман