16
\$\begingroup\$

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
\$\endgroup\$
11
  • 4
    \$\begingroup\$ Interesting challenge, but this could use some test cases so people can validate their answers. \$\endgroup\$ Commented May 26, 2016 at 15:59
  • 3
    \$\begingroup\$ Shouldn't the Q be lowercase? The actual shape looks like a q rather than a Q \$\endgroup\$
    – Luis Mendo
    Commented May 26, 2016 at 16:01
  • \$\begingroup\$ Will the input integers be single-digit, limited number of digits or unlimited? \$\endgroup\$ Commented May 26, 2016 at 16:27
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ Commented May 26, 2016 at 16:49
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ Commented May 26, 2016 at 21:09

4 Answers 4

7
\$\begingroup\$

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
$ 
\$\endgroup\$
3
  • 1
    \$\begingroup\$ I'll go ahead and award this since nobody seems to be trying this one anymore. \$\endgroup\$ Commented Jun 7, 2016 at 12:40
  • \$\begingroup\$ Thanks Darrel - It was a fun, interesting challenge. If you want more answers, you might consider putting a bounty on it. \$\endgroup\$ Commented Jun 7, 2016 at 18:09
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Jun 8, 2016 at 15:37
3
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$
    – Neil
    Commented May 26, 2016 at 20:18
2
\$\begingroup\$

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>

\$\endgroup\$
0
1
\$\begingroup\$

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
\$\endgroup\$
2
  • \$\begingroup\$ I promise that I will not use golflangs to solve this problem (it would probably cost not more than 50 bytes) \$\endgroup\$
    – Leaky Nun
    Commented May 28, 2016 at 13:58
  • \$\begingroup\$ 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? \$\endgroup\$ Commented May 31, 2016 at 15:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.