Correct way to add numbers to get lots of 8's

16

Inspired by this question which was further inspired by this one, write a program which takes two integers and adds them in a unique way, by performing an OR operation on the segments used to display them in a 7-segment display. For reference, the digits are represented in the following way:

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

Note that the 1 uses the two segments on the right, not the left. There are two special characters that can be produced this way which are not numbers. See the addition table below:

  | 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

Useful observations:

  • Any digit plus itself equals itself
  • 8 plus any digit equals 8
  • 2 plus 1, 3, or 7 equals the letter 'a' (must be lower-case)
  • 4 plus 7 equals either 'q' or 'Q', your choice
  • Numbers should be right-aligned, so the digits should be added from right to left. If one number has more digits than the other, the extra digits at the beginning should be unchanged. There are no leading 0's, unless the number is exactly 0.
  • All numbers will be 0 or greater. You don't need to handle a '-' sign. (Mainly because there's no good fit for the sum of a '-' and a '1' or '7'.)

Your program should accept 2 integers in any format you choose, and output a string containing their "sum" when calculated in this manner. This is code-golf, so your program should be as small as possible.

Examples:

  • Input: 12345, 123. Output: 12389
  • Input: 88888, 42. Output: 88888
  • Input: 0, 23. Output: 28
  • Input: 120, 240. Output: a80
  • Input: 270, 42. Output: 2Q8 (or 2q8)
  • Input: 1234567890, 1234567890. Output: 1234567890

Darrel Hoffman

Posted 2016-05-26T15:42:05.813

Reputation: 353

4Interesting challenge, but this could use some test cases so people can validate their answers. – AdmBorkBork – 2016-05-26T15:59:11.943

3Shouldn't the Q be lowercase? The actual shape looks like a q rather than a Q – Luis Mendo – 2016-05-26T16:01:36.467

Will the input integers be single-digit, limited number of digits or unlimited? – Digital Trauma – 2016-05-26T16:27:43.650

@DigitalTrauma - Numbers can be any number of digits (within reason, depending on the limitations of your chosen language). For simplicity, the numbers should be right-aligned, just as in normal addition. (So unlike the linked puzzle where 22+4=82, in this challenge it would be 28.) – Darrel Hoffman – 2016-05-26T16:48:17.670

1@LuisMendo - I suppose it could go either way. I'll leave that up to your discretion. The a should definitely be lower case though, since A looks completely different. – Darrel Hoffman – 2016-05-26T16:49:48.493

- plus 1 equals and - plus 7 equals ! – Adám – 2016-05-26T19:59:31.487

@Zgarb - Done. Also added a test that adds a value to itself (which should simply return the same number unchanged). – Darrel Hoffman – 2016-05-26T21:07:34.927

2@Adám - Yeah, I thought about that, but figured not everybody has access to Unicode characters in their golfing languages of choice, so it'd be unfair to expect them to handle that. – Darrel Hoffman – 2016-05-26T21:09:01.120

Can input be an array of arrays of digits? Something like {[1 2 3 4 5] [1 2 3]} for the first test case – Luis Mendo – 2016-05-27T00:54:18.087

@LuisMendo - I don't know - what's the usual practice on this sort of thing? I did say "any format you choose", but that might be stretching it a bit? I'll let the community decide whether that's fair or not. – Darrel Hoffman – 2016-05-27T13:22:54.090

@DarrelHoffman Yes, I agree it might be stretching – Luis Mendo – 2016-05-27T13:46:55.197

Answers

7

Bash + Common Linux utilities, 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

Note the ^? in the source should be replaced with an ASCII 0x7f character.

The string s is each 7 segment digit 0-9, a, Q encoded with each segment corresponding to a bit of an ASCII char.

The h() function transliterates the input number from decimal to the encoding specified by s, then outputs the result as a raw hex string.

The two resulting raw hex strings are ORed together using regular bash arithmetic, then output by dc's P command as a bytestream. This bytestream is then transliterated back to decimal + a + Q and output.

Note also that when using the <<< bash herestring construct in function h() a newline is implicitly appended to the redirected string. This doesn't matter - it is simply translated to 0x0a at the end of each hex string; when the two hex numbers are ORed together, the result is still 0x0a in the last char which doesn't get transliterated and thus simply translates back to a newline which is output after the result.

Test output:

$ for testcase in \
> "12345 123" \
> "88888 42" \
> "0 23" \
> "1234 56789" \
> "4 7"; do 
> ./7segadd.sh $testcase
> done
12389
88888
28
58a89
Q
$ 

Digital Trauma

Posted 2016-05-26T15:42:05.813

Reputation: 64 644

1I'll go ahead and award this since nobody seems to be trying this one anymore. – Darrel Hoffman – 2016-06-07T12:40:52.307

Thanks Darrel - It was a fun, interesting challenge. If you want more answers, you might consider putting a bounty on it. – Digital Trauma – 2016-06-07T18:09:32.010

Nah, I don't have enough rep on this site to go spending it all on bounties. (I can't even test this one since I'm not running Linux, I'm just giving the community the benefit of the doubt.) I just kind of threw this together on a whim based on another question anyhow. – Darrel Hoffman – 2016-06-08T15:37:14.340

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]

Replace the with a DEL character (0x7F).

Calling f("12345", "123") prints 12389.

Lynn

Posted 2016-05-26T15:42:05.813

Reputation: 55 648

There are three sets of values for which that %13 trick works. Obviously you went for the set which had no characters below 40, but for my JavaScript translation I chose the shortest set. The third set is the longest in JavaScript, it would have been 111,5,118,117,29,121,123,37,127,125. – Neil – 2016-05-26T20:18:06.780

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

Saved 14 bytes by shamelessly stealing @Lynn's %13 trick.

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

Posted 2016-05-26T15:42:05.813

Reputation: 95 035

1

Java, 170 bytes

This is terribly long... but this is Java anyway.

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

Full program, with ungolfed code

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

All output (all duplicated once)

12389
88888
23
a80
2q8
1234567890

Leaky Nun

Posted 2016-05-26T15:42:05.813

Reputation: 45 011

I promise that I will not use golflangs to solve this problem (it would probably cost not more than 50 bytes) – Leaky Nun – 2016-05-28T13:58:09.973

I never said people couldn't use golf languages for this - I'm honestly surprised nobody has yet. Anyhow, even without that you could probably save some bytes using a Java 8 lambda? – Darrel Hoffman – 2016-05-31T15:46:20.023