Find every digit from the largest column

14

1

Here's a relatively simple challenge for you:

Given a list of positive integers:

  • Line them up in a grid, and sum each column. For example, if the input was [123, 7, 49, 681], the grid would look like this:

     1  2  3
     7 
     4  9 
     6  8  1 
    

    And the sum of each column would be [18, 19, 4]:

     1  2  3
     7 
     4  9 
     6  8  1 
     --------
     18 19 4
    
  • Find the maximum of these sums, which in this case would be 19, and then

  • Output every digit that is at the same index as this maximum column. In this case, that would be

    2
    9
    8
    

    You do not have to output these numbers in any particular order. Note that there are only three outputs, even though we had 4 inputs. In the case of a tie, pick the earliest index. For example, if the input was [25, 223, 302], your grid is:

    2  5
    2  2  3
    3  0  2
    -------
    7  7  5
    

    You should output

    2
    2
    3
    

You can print these numbers in any format you like. List format, newline separated, space separated, etc. You may not take the input as a 2D array of digits, e.g.

[[1, 2, 3],
[7],
[4, 9],
[6, 8, 1]

But other than that, you can take input as a list of strings, a list of digits, or any other reasonable format.

You may also assume that all inputs will be valid and contain at least two numbers.

As usual, the shortest answer in bytes wins!

Test IO:

#Input                      #Output
[1, 11, 111, 1111]      --> [1, 1, 1, 1]
[1, 12, 123]            --> [2, 2]
[987654321, 111]        --> [9, 1]
[111, 123456789]        --> [9]
[4, 8, 15, 16, 23, 42]  --> [4, 8, 1, 1, 2, 4]
[4, 8, 12, 26, 27, 38]  --> [2, 6, 7, 8]
[24, 53]                --> [2, 5]
[12, 304, 506]          --> [4, 6]
[30, 285, 121]          --> [0, 8, 2]

James

Posted 2016-09-03T06:29:52.770

Reputation: 54 537

The title is difficult to understand. The problem seems to lie with the expression, "largest column". Perhaps something like, "Find the column with the greatest total" or "Column addition: find the maximum sum". – DavidC – 2016-09-03T20:52:30.620

The problem statement says "given a list of positive integers", but one of the examples has a 0. Zero is usually not considered positive in english. – Ton Hospel – 2016-09-05T05:51:25.880

@tonhospel Which one? The one with 302? That only has a zero after you split up the columns. – James – 2016-09-05T05:53:28.567

Right, I misintereted the input format. Fixing my submission.. – Ton Hospel – 2016-09-05T06:26:27.253

Answers

6

Haskell, 63 bytes

import Data.Lists
argmax sum.transpose.map(map(read.pure).show)

Usage example: argmax sum.transpose.map(map(read.pure).show) $ [12,304,506] -> [4,6].

How it works:

                     map                       -- for each number
                         map(read.pure).show   -- turn into list of digits
           transpose                           -- transpose the list of list
argmax sum                                     -- find the element with the
                                               -- largest sum

nimi

Posted 2016-09-03T06:29:52.770

Reputation: 34 639

5

Jelly, 6 bytes

DZṚSÞṪ

Try it online!. This is a relatively straightforward implementation of the question.

D              Convert each number in the input to a list of digits, e.g.
               [353, 2247] -> [[3, 5, 3], [2, 2, 4, 7]]
 Z             Zip the lists together, e.g. [[3, 2], [5, 2], [3, 4], [7]]
  Ṛ            Reverse the list of lists so that first occurrences are now
               at the end, e.g. [[7], [3, 4], [5, 2], [3, 2]]
   SÞ          Sort by sum - this uses Python's sorted function, which is stable
               so equal elements end up in order of appearance, e.g.
               [[3, 2], [7], [3, 4], [5, 2]]
     Ṫ         Tail - get the last element, e.g. [5, 2]

Sp3000

Posted 2016-09-03T06:29:52.770

Reputation: 58 729

Not to detract from your solution, but isn't this actually 11 bytes, given it contains some UTF-8 multi-byte characters. – Joshua – 2016-09-04T03:58:15.820

3

@Joshua It's a bit weird, but Jelly uses its own custom code page that encodes each of the 256 characters it understands in a single byte. It's not usually scored in UTF-8, much the same way APL wouldn't be.

– Sp3000 – 2016-09-04T04:15:21.210

Ahh, ok. Thanks for the explanation. – Joshua – 2016-09-05T04:09:12.717

2

Ruby, 100 97 bytes

a=$<.map &:chomp
puts a.map(&:size).max.times.map{|i|a.map{|e|e[i]}.compact}.max_by{|e|eval e*?+}

cia_rana

Posted 2016-09-03T06:29:52.770

Reputation: 441

eval e*?+ is great! Also you can just do $<.map; no need to splat it into an array. – Jordan – 2016-09-03T16:41:21.360

@Jordan Thank you for your advice! – cia_rana – 2016-09-03T17:18:51.503

1

Javascript (ES6), 108 103 100 bytes

It's a bit verbose and could probably be golfed some more with a different approach. I wish I could get rid of this .filter(n=>n).

Saved 5 bytes thanks to Neil
Saved 3 bytes thanks to edc65

l=>l.map(n=>[...n].map((d,x)=>(m=(s[x]=(s[x]|0)-d)<m?s[c=x]:m,d)),s=[m=0]).map(n=>n[c]).filter(n=>n)

Demo

let f =
l=>l.map(n=>[...n].map((d,x)=>(m=(s[x]=(s[x]|0)-d)<m?s[c=x]:m,d)),s=[m=0]).map(n=>n[c]).filter(n=>n)

console.log(f(["1", "11", "111", "1111"]).join`,`);          // --> [1, 1, 1, 1]
console.log(f(["1", "12", "123"]).join`,`);                  // --> [2, 2]
console.log(f(["987654321", "111"]).join`,`);                // --> [9, 1]
console.log(f(["111", "123456789"]).join`,`);                // --> [9]
console.log(f(["4", "8", "15", "16", "23", "42"]).join`,`);  // --> [4, 8, 1, 1, 2, 4]
console.log(f(["4", "8", "12", "26", "27", "38"]).join`,`);  // --> [2, 6, 7, 8]
console.log(f(["24", "53"]).join`,`);                        // --> [2, 5]
console.log(f(["12", "304", "506"]).join`,`);                // --> [4, 6]
console.log(f(["30", "285", "121"]).join`,`);                // --> [0, 8, 2]

Arnauld

Posted 2016-09-03T06:29:52.770

Reputation: 111 334

If you use (d,x)=>(...,d) then the inner map returns a copy of k, thus saving you having to assign k, which saves you 4 bytes. – Neil – 2016-09-03T16:22:35.113

I think negating m, i.e. (s[x]=(s[x]|0)-d)<m, saves you a byte. – Neil – 2016-09-03T16:24:14.020

@Neil - Good eye, as usual ;) – Arnauld – 2016-09-03T16:30:12.873

1I tried a filter-less approach. It turned out to be... 103 bytes! a=>a.map(n=>[...n+''].map((d,i)=>(t=s[i]=s[i]||[0],t.push(d),(t[0]-=d)<m?r=t:0)),s=[],m=0)&&r.slice(1) – Neil – 2016-09-04T09:58:17.707

You can get the input as a list of string and not numbers. That way you can cut the +'' – edc65 – 2016-09-05T08:19:51.893

1

Mathematica 82 bytes

This pads the digits of each number with x's to the right, transposes the matrix, removes the dummy x's, orders by sum of the digits and takes the greatest.

SortBy[#~Select~NumberQ&/@Transpose[PadRight[#,30,x]&/@IntegerDigits@#],Tr][[-1]]&

There ought to be some way to use the superscript-T form of Transpose to save a few bytes.

DavidC

Posted 2016-09-03T06:29:52.770

Reputation: 24 524

1

Perl, 49 48 bytes

Includes +1 for -p

Run with the input on STDIN, prints to STDOUT the column numbers prefixed by +

lcolumn.pl
123
7 
49 
681

lcolumn.pl:

#!/usr/bin/perl -p
s/./@;[@-].="+$&"/eg}{($_)=sort{eval"$b<=>$a"}@

Ton Hospel

Posted 2016-09-03T06:29:52.770

Reputation: 14 114

1

Pyth, 5 8 bytes

esDsMM.T

Takes in input as a list of strings, outputs as a nothing-separated list of digits.

Try it online!

Explanation:

      .T  Transpose input to zip together corresponding columns
   sMM    Cast to digit lists
 sD       sort(D) by (s)um
e         take last element, implicitly print

Steven H.

Posted 2016-09-03T06:29:52.770

Reputation: 2 841

Hmm, this doesn't seem to work for all testcases? I've tried the last one, and it gives a different output than in OP's question.

– Kevin Cruijssen – 2016-09-05T08:43:04.787

@KevinCruijssen Yeah, I messed up. It was sorting by integer value instead because of the strings messing with Pyth's overloading. – Steven H. – 2016-09-05T20:09:54.230

0

Pyth, 11 bytes

h.MsZ.TmjdT

A program that takes input of a list of integers on STDIN and prints a list.

Try it online

How it works

h.MsZ.TmjdT  Program. Input: Q
        j T   Yield the base-10 representation, giving a list of digits
       m d   Map that over Q (implicit input fill)
     .T      Justified transpose, giving each column as a list
 .MsZ        Filter the above by maximum sum
h            First element of above
             Implicitly print

TheBikingViking

Posted 2016-09-03T06:29:52.770

Reputation: 3 674

0

JavaScript (ES6), 90

(l,x)=>[...l+0].map((t,i)=>l.map(n=>(n=n[i])&&(v-=n,t.push(n)),v=t=[])|v>=x||(x=v,r=t))&&r

f=(l,x)=>[...l+0].map((t,i)=>l.map(n=>(n=n[i])&&(v-=n,t.push(n)),v=t=[])|v>=x||(x=v,r=t))&&r

;[
 [[123, 7, 49, 681]       , [2,9,8]]
,[[25, 223, 302]          , [2, 2, 3]]
,[[1, 11, 111, 1111]      , [1, 1, 1, 1]]
,[[1, 12, 123]            , [2, 2]]
,[[987654321, 111]        , [9, 1]]
,[[111, 123456789]        , [9]]
,[[4, 8, 15, 16, 23, 42]  , [4, 8, 1, 1, 2, 4]]
,[[4, 8, 12, 26, 27, 38]  , [2, 6, 7, 8]]
,[[24, 53]                , [2, 5]]
,[[12, 304, 506]          , [4, 6]]
,[[30, 285, 121]          , [0, 8, 2]]]
.forEach(t=>{
  var i=t[0], o=t[1], r, ok
  i=i.map(x=>x+'') // convert i to a string list
  r=f(i) 
  ok = (r+'')==(o+'') // compare r and o as comma separated strings
  console.log(ok?'OK':'KO', i+' -> '+ r)
  
})

edc65

Posted 2016-09-03T06:29:52.770

Reputation: 31 086

0

Pyth - 9 bytes

esD_.TjRT

Test Suite.

Maltysen

Posted 2016-09-03T06:29:52.770

Reputation: 25 023