20
\$\begingroup\$

Challenge

Calculate the strange sum of two natural numbers (also known as lunar addition):

Given A=... a2 a1 a0 and B=... b2 b1 b0 two natural numbers written in the decimal base, the strange sum is defined, based on the maximum operation, as: A+B=... max(a2,b2) max(a1,b1) max(a0,b0)

   ...         a2         a1         a0
 + ...         b2         b1         b0
 ----------------------------------------
   ...  max(a2,b2) max(a1,b1) max(a0,b0)

Input

Two natural numbers

All the following is allowed:

  • Zero-padded strings (same length)
  • Left-space-padded strings
  • Right-space-padded strings
  • Array of two padded strings
  • 2D space-padded char array

Output

A natural numbers

Example

1999+2018-->2999
17210+701-->17711
32+17-->37
308+250-->358
308+25-->328

Rules

  • The input and output can be given in any convenient format (choose the most appropriate format for your language/solution).
  • No need to handle negative values or invalid input
  • Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
  • If possible, please include a link to an online testing environment so other people can try out your code!
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.
\$\endgroup\$
  • 3
    \$\begingroup\$ also known as lunar addition \$\endgroup\$ – TFeld Nov 15 '18 at 14:38
  • 3
    \$\begingroup\$ Can we take the input as zero-padded strings (same length)? \$\endgroup\$ – TFeld Nov 15 '18 at 14:44
  • 1
    \$\begingroup\$ I think this is a bit too trivial. Weird that has not been asked before \$\endgroup\$ – Windmill Cookies Nov 15 '18 at 14:45
  • 1
    \$\begingroup\$ Can we have the numbers in the same length? Like 17210 00701 instead of 17210 701 ? \$\endgroup\$ – Windmill Cookies Nov 15 '18 at 14:57
  • 8
    \$\begingroup\$ I fail to see what input formats are allowed exactly. The input format is very important in this challenge, as some formats allow much easier processing. What of the following are allowed? 1) Zero-padded strings (same length) 2) Left-space-padded strings 3) Right-space-padded strings. 4) Array of two padded strings. 5) 2D space-padded char array. Voting to close and downvoting for now; I will happily remove my votes when solved \$\endgroup\$ – Luis Mendo Nov 15 '18 at 19:01

30 Answers 30

14
\$\begingroup\$

Python 2, 20 bytes

lambda*a:map(max,*a)

Try it online!

I/O as 0-pre-padded lists of digits.

| improve this answer | |
\$\endgroup\$
12
\$\begingroup\$

Jelly, 1 byte

»

Try it online!

I/O as 0-pre-padded lists of digits.

| improve this answer | |
\$\endgroup\$
7
\$\begingroup\$

R, 68 65 bytes

function(x)apply(outer(x,10^(max(nchar(x)):1-1),`%/%`)%%10,2,max)

Try it online!

Input as integers, output as list of digits.

If zero-padding lists of digits was allowed, then simply pmax would suffice.

| improve this answer | |
\$\endgroup\$
6
\$\begingroup\$

MATL, 2 bytes

X>

Choose the most appropriate format for your language/solution

The input format is: 2D char array of two rows, each corresponding to a line, with the shorter number left-padded with spaces. For example

17210
  701

which in MATL is defined as

['17210'; '  701']

Try it online!

Explanation

      % Implicit input: 2D char array with two rows 
X>    % Take maximum of (code points of) each column
      % Implicit display
| improve this answer | |
\$\endgroup\$
5
\$\begingroup\$

Python 2, 73 60 56 bytes

lambda a,b:map(max,zip(a.rjust(len(b)),b.rjust(len(a))))

Try it online!

Takes input as two strings, and returns a list of digits


Alternative:

Takes input as two integers; same output

Python 2, 60 59 bytes

lambda*i:map(max,zip(*['%*d'%(len(`max(i)`),v)for v in i]))

Try it online!

| improve this answer | |
\$\endgroup\$
5
\$\begingroup\$

Java 10, 78 57 bytes

a->b->{for(int i=a.length;i-->0;)if(a[i]<b[i])a[i]=b[i];}

Input as two space-padded character arrays.

Modifies the first input-array instead of returning a new one to save 21 bytes (thanks to @OlivierGrégoire).

Try it online.

Explanation:

a->b->{            // Method with two char-array parameters and String return-type
  for(int i=a.length;i-->0;)
                   //  Loop `i` in the range (length, 0]:
    if(a[i]<b[i])  //   If the `i`'th character in input `a` is smaller than in input `b`:
      a[i]=b[i];}  //    Change the `i`'th character in `a` to the `i`'th character of `b`
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ a->b->{for(int i=a.length;i-->0;)if(a[i]<b[i])a[i]=b[i];} (57 bytes). Reuse a as output to gain much, much bytes. \$\endgroup\$ – Olivier Grégoire Nov 16 '18 at 12:30
  • \$\begingroup\$ @OlivierGrégoire Ah, can't believe I hadn't thought of that. Thanks! :D \$\endgroup\$ – Kevin Cruijssen Nov 16 '18 at 12:59
4
\$\begingroup\$

J, 14 12 bytes

-2 bytes thanks to Jonah

(>./@,:)&.|.

Try it online!

Input and output as list(s) of digits

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ 12 bytes: (>./@,:)&.|.. Try it online! \$\endgroup\$ – Jonah Nov 15 '18 at 17:06
  • 1
    \$\begingroup\$ @Jonah Of course! Thank you! \$\endgroup\$ – Galen Ivanov Nov 15 '18 at 18:05
  • 1
    \$\begingroup\$ if you’re looking for a challenge, see if you can improve this monstrosity: codegolf.stackexchange.com/a/175968/15469 \$\endgroup\$ – Jonah Nov 15 '18 at 21:03
4
\$\begingroup\$

Japt, 9 8 7 bytes

Takes input as an array of digit arrays.

mÔÕÔËrw

Try it

m            :Map
 Ô           :  Reverse
  Õ          :Transpose
   Ô         :Reverse
    Ë        :Map
     r       :  Reduce by
      w      :  Maximum

If taking zero-padded arrays as input is permitted (it would currently fall under a "convenient format" but I suspect that's not the challenger's intent) then this can be 3 bytes.

íwV

Try it

í       :Interleave the first input
  V     :With the second
 w      :Reduce each pair by maximum
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Here's another 8 byte solution with a different strategy and simpler input format. maybe you can shave a byte from that? \$\endgroup\$ – Kamil Drakari Nov 15 '18 at 17:13
  • \$\begingroup\$ @KamilDrakari: Uncanny - I was just updating with the exact same solution! \$\endgroup\$ – Shaggy Nov 15 '18 at 17:14
  • \$\begingroup\$ Interestingly, the version that separates the "transpose" and "reduce" steps is also 8 bytes because of better shortcuts \$\endgroup\$ – Kamil Drakari Nov 15 '18 at 17:20
  • \$\begingroup\$ @KamilDrakari, oh, we have a shortcut for y now? I did not know that. Here's another way, also 8 bytes. \$\endgroup\$ – Shaggy Nov 15 '18 at 17:23
  • \$\begingroup\$ Ooh, that's a neat trick with '. I don't know whether that would ever save bytes, but it's definitely cool. \$\endgroup\$ – Kamil Drakari Nov 15 '18 at 17:25
4
\$\begingroup\$

Haskell, 40 bytes

a#b=zipWith max(p b++a)$p a++b
p=(' '<$)

Input/output as strings, try it online!

Explanation

The function p replaces each character by a space, using p b++a and p a++b are thus the same length. This way we can use zipWith without losing any elements, using max with it works because a (space) has lower codepoint than any of the characters ['0'..'9'].

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Perl 6, 37 bytes

{[R~] roundrobin($_».reverse)».max}

Try it online!

Takes input as a list of lists of digits.

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

05AB1E, 9 6 5 bytes

-3 thanks to Emigna
-1 thanks to Shaggy

íζ€àR

Takes input as a list of lists of digits

í      # Reverse both inputs
 ζ     # Zip
  ۈ   # Keep the bigger digits
    R  # Reverse

Try it online! or Try all test cases

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ €R can be í. Also, I don't think you need €þ as number > space \$\endgroup\$ – Emigna Nov 15 '18 at 16:50
  • \$\begingroup\$ @Emigna Thanks! I thought I tried it without €þ and it didn't work, but now it does... \$\endgroup\$ – Riley Nov 15 '18 at 16:59
  • \$\begingroup\$ Do you need the J at the end? \$\endgroup\$ – Shaggy Nov 15 '18 at 19:57
  • \$\begingroup\$ @Shaggy No, I guess I don't. Thanks! \$\endgroup\$ – Riley Nov 15 '18 at 21:00
  • \$\begingroup\$ It's lame, but the rules allow a 3 byte solution by taking a 2D space-padded char array.. \$\endgroup\$ – Kevin Cruijssen Nov 16 '18 at 8:40
4
\$\begingroup\$

Perl 6, 15 bytes

{[~] [Zmax] $_}

Try it online!

Takes input as a list of space padded arrays of characters, though for this challenge the lax input format makes it rather boring. Alternatively, here's the program that takes a list of two integers instead:

Perl 6, 41 bytes

{+[~] [Zmax] $_>>.fmt("%{.max}d")>>.comb}

Try it online!

If you don't mind a huge amount of whitespace, you can also remove the + from the front.

Explanation:

{                                       }  # Anonymous code block
             $_>>    # Map each integer to 
                 .fmt("%{.max}d") # The number padded by the max of the list spaces
                                 >>.comb   # And split each to list of characters
      [Zmax]  # Get the max of each digit at each index
              # This works because space is coerced to 0
              # Otherwise we would have to add a 0 to the formatting string
  [~]   # Join the list of digits and spaces
 +      # And coerce the string to a number to get rid of leading whitespace
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 51 49 bytes

NB: This answer was posted before the loose I/O formats were explicitly allowed. With zero-padded arrays of digits, this can be done in 33 bytes, (but is much less interesting, IMHO).

Takes input as two integers. Returns an integer.

f=(a,b,t=10)=>a|b&&(a%t<b%t?b:a)%t+t*f(a/t,b/t)|0

Try it online!

Commented

f = (                     // f = recursive function taking:
  a,                      //   a = first integer
  b,                      //   b = second integer
  t = 10                  //   t = 10 (which is used 6 times below)
) =>                      //
  a | b                   // bitwise OR between a and b to test whether at least one of
                          // them still has an integer part
  &&                      // if not, stop recursion; otherwise:
  (                       //
    a % t < b % t ? b : a // if a % 10 is less than b % 10: use b; otherwise: use a
  ) % t +                 // isolate the last decimal digit of the selected number
  t *                     // add 10 times the result of
  f(a / t, b / t)         // a recursive call with a / 10 and b / 10
  | 0                     // bitwise OR with 0 to isolate the integer part

Alternate version

Same I/O format.

f=(a,b)=>a|b&&[f(a/10,b/10)]+(a%10<b%10?b:a)%10|0

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You can get much shorter if you assume your input to be a 2d space padded char array. \$\endgroup\$ – kamoroso94 Nov 15 '18 at 22:20
  • \$\begingroup\$ Hi! Could you provide some explanation? I ""tried"" to do this challenge in JavaScript but I failed and would like to see how your solution works :) \$\endgroup\$ – Neyt Nov 16 '18 at 9:35
  • 1
    \$\begingroup\$ @Neyt I've added a commented version. The alternate version is using the same logic; the only difference is that we add the next digit to the left as a string instead of multiplying the result of the recursive call by 10. \$\endgroup\$ – Arnauld Nov 16 '18 at 9:53
  • \$\begingroup\$ @Arnauld Thank you! :) \$\endgroup\$ – Neyt Nov 16 '18 at 9:54
2
\$\begingroup\$

Tcl, 156 bytes

proc S a\ b {join [lmap x [split [format %0[set l [expr max([string le $a],[string le $b])]]d $a] ""] y [split [format %0$l\d $b] ""] {expr max($x,$y)}] ""}

Try it online!

Not very golfy, but I had to give a try on it. Will golf it later!

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Batch, 120 bytes

@set/aw=1,x=%1,y=%2,z=0
@for /l %%i in (0,1,9)do @set/a"z+=w*((v=y%%10)+(v-=x%%10)*(v>>4)),y/=10,x/=10,w*=10
@echo %z%

Takes input as command-line parameters. 188-byte version works on arbitrary length integers:

@set/px=
@set/py=
@set z=
:l
@if %x:~-1% gtr %y:~-1% (set z=%x:~-1%%z%)else set z=%y:~-1%%z%
@set x=%x:~,-1%
@set y=%y:~,-1%
@if "%x%" neq "" if "%y%" neq "" goto l
@echo %x%%y%%z%

Takes input on STDIN.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Twig, 125 bytes

When I saw this challenge, I though: "let me use a template language! sure is a good fit"

I was wrong ... so wrong .... ... But was fun!

{%macro a(a,b,s='')%}{%for k,x in a|reverse|split('')%}{%set s=max(x,(b|reverse|split('')[k]))~s%}{%endfor%}{{s}}{%endmacro%}

This requires that "strict_variables" is set to false (default value).

To use this macro, you can do like this:

{% import 'file.twig' as my_macro %}

{{ my_macro.a(195,67) }}

Should display 167.

You can try this in https://twigfiddle.com/rg0biy
("strict_variables" set to off, it is on by default on the website)

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Husk, 5 bytes

↔¤żY↔

Conveniently takes input/output as list of digits, try it online or verify all!

Explanation

↔¤żY↔  -- example inputs [1,4] [3,2]
 ¤  ↔  -- reverse the arguments of: [4,1] [2,3]
  żY   -- | zipWith (keeping elements of longer) max: [4,3]
↔      -- reverse: [3,4]
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Stax, 5 bytes

|>E:o

Run and debug it

This program takes input as an array of strings.

|>  Right align inputs (filling with \0)
E   "Explode" array onto stack separately
:o  "Overlay" Keep the maximum element respective element from two arrays.

Run this one

This is the first time I've seen a use for the overlay instruction "in the wild".

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 153 bytes

	X =INPUT
	Y =INPUT
	Y =DUPL(0,SIZE(X) - SIZE(Y)) Y
S	X LEN(1) . A REM . X	:F(O)
	Y LEN(1) . B REM . Y
	O =O GT(A,B) A	:S(S)
	O =O B	:(S)
O	OUTPUT =O
END

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Pyth, 5 bytes

meSdC

Takes input as array of two space-padded strings.

meSd       map greatest
    C      on the transpose of input

Try it here.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Japt, 4 bytes

Input is taken as a an array of two 0-padded number arrays.

y_rw

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Ceylon, 55 / 99

With 0- or space-padded strings of same length (returning an iterable of characters):

function t(String a,String b)=>zipPairs(a,b).map(max);

With 0- or space-padded strings (returning a String):

String t(String a,String b)=>String(zipPairs(a,b).map(max));

With strings of possibly different length (returning a String):

String u(String a,String b)=>String(zipPairs(a.padLeading(b.size),b.padLeading(a.size)).map(max));
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

C# (.NET Core), 57 bytes

a=>b=>a.Select((x,i)=>a[i]>b[i]?x:b[i])

-1 bytes by adding currying

Try It Online

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You can save 3 bytes when you use x instead of a[i] in condition \$\endgroup\$ – Jirka Picek Jan 2 at 7:51
1
\$\begingroup\$

Ruby, 25 bytes

->a,b{a.zip(b).map &:max}

Try it online!

Pre-padded list blah blah. (Although it feels a little like cheating.)

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Retina 0.8.2, 39 bytes

+`^(.*)(.)¶(.*)(.)
$1¶$3¶$2$4
%O`.
¶.?

Try it online! Link includes test suite. Previous 45-byte Retina 1 version accepts unpadded strings:

P^`.+
+`^(.*)(.)¶(.*)(.)
$1¶$3¶$2$4
%O`.
¶.?

Try it online! Link includes test suite. Explanation:

P^`.+

Pad both values to the same length. (Retina 1 only. There are ways of emulating this in Retina 0.8.2 but they are not very golfy.)

+`^(.*)(.)¶(.*)(.)
$1¶$3¶$2$4

Transpose the values.

%O`.

Sort each pair into order.

¶.?

Delete all the low digits and surplus newlines.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 8 bytes

⭆θ⌈⟦ι§ηκ

Try it online! Link is to verbose version of code. Explanation:

 θ          First input
⭆           Map over characters and join
  ⌈         Maximum of
   ⟦        List of
    ι       Current character of first input and
      η     Second input
     §      Indexed by
       κ    Current index
            Implicitly print

10-byte version "adds" any number of padded strings:

⭆§θ⁰⌈Eθ§λκ

Try it online! Link is to verbose version of code. Previous 14-byte version accepts unpadded strings:

⭆◧θLη⌈⟦ι§◧ηLθκ

Try it online! Link is to verbose version of code. Explanation:

  θ             First input
 ◧              Padded to
   L            Length of
    η           Second input
⭆               Map over characters and join
     ⌈          Maximum of
      ⟦         List of
       ι        Current character of first input and
          η     Second input
         ◧      Padded to
           L    Length of
            θ   First input
        §       Indexed by
             κ  Current index
                Implicitly print

17-byte version "adds" any number of strings:

≔⌈EθLιη⭆η⌈Eθ§◧ληκ

Try it online! Link is to verbose version of code.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ The question has been changed so the strings can be input as padded \$\endgroup\$ – ASCII-only Nov 19 '18 at 6:59
  • \$\begingroup\$ Nitpicking, but you missed a close paren in the first verbose version :P \$\endgroup\$ – ASCII-only Nov 19 '18 at 23:30
  • \$\begingroup\$ @ASCII-only If only TIO matched parens for me ;-) \$\endgroup\$ – Neil Nov 20 '18 at 1:47
1
\$\begingroup\$

Wren, 74 bytes

Fn.new{|i|(0...i.count/2).map{|j|i[j]>i[j+i.count/2]?i[j]:i[j+i.count/2]}}

Try it online!

Input is a single list of the two operands, e.g.

[1, 7, 2, 1, 0,
 0, 0, 7, 0, 1]

Explanation

Now I need to figure out a formula for maximum.

Fn.new{|i|                                                               } // New anonymous function with the operand i
          (0...i.count/2)                                                  // Define an exclusive range from 0 to half the input
                         .map{|j|                                       }  // Turn every item of the list into ...
                                 i[j]>i[j+i.count/2]?i[j]:i[j+i.count/2]   // ... The maximum between i[j] and i[j+i.count/2]
                                                                           // (which is simply the other list's index at the same position)
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -MList::Util=max -F, 22 bytes

say map{max $_,getc}@F

Try it online!

Input must be 0 or space padded so that the entries are the same length.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

APL(NARS), 51 chars, 102 bytes

{k←⌈/≢¨(a b)←⍎¨∘⍕¨⍺⍵⋄f←{((k-≢⍵)⍴0),⍵}⋄10⊥(f a)⌈f b}

test:

  h←{k←⌈/≢¨(a b)←⍎¨∘⍕¨⍺⍵⋄f←{((k-≢⍵)⍴0),⍵}⋄10⊥(f a)⌈f b}
  1999 h 2018
2999
  17210 h 701
17711
  32 h 17
37
  308 h 250
358
  308 h 25
328
| improve this answer | |
\$\endgroup\$
-1
\$\begingroup\$

Mathematica 50 bytes

a = 543; b = 791;

FromDigits@MapThread[Max, IntegerDigits /@ {a, b}]

(* 793 *)

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Can you add a TIO? I don't know Mathematica but I suspect this might fail if the 2 inputs don't have an equal number of digits. \$\endgroup\$ – Shaggy Nov 15 '18 at 23:22
  • 1
    \$\begingroup\$ I think you're taking input through predefined variables, which would make this a snippet, which is not allowed. Submissions should be either a function or a full program \$\endgroup\$ – Jo King Nov 16 '18 at 2:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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